![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #include <APPLICATIONS/session/client/VoIP.hpp> 00029 00030 using namespace applications::session::client; 00031 00032 STATIC_FACTORY_REGISTER_WITH_CREATOR(applications::session::client::VoIP, 00033 applications::session::Session, 00034 "client.VoIP", wns::PyConfigViewCreator); 00035 00036 VoIP::VoIP(const wns::pyconfig::View& _pyco) : 00037 Session(_pyco), 00038 stateTransitionDistribution(NULL), 00039 cnCounter(0), 00040 receivedFirst(false) 00041 { 00042 wns::pyconfig::View sTVConfig(_pyco, "stateTransition"); 00043 std::string sTVName = sTVConfig.get<std::string>("__plugin__"); 00044 stateTransitionDistribution = wns::distribution::DistributionFactory::creator(sTVName)->create(sTVConfig); 00045 00046 settlingTime = _pyco.get<wns::simulator::Time>("settlingTime"); 00047 00048 iat = _pyco.get<wns::simulator::Time>("packetIat"); 00049 voicePacketSize = _pyco.get<Bit>("voicePacketSize"); 00050 /* Packet size includes 12 bytes RTP header. */ 00051 voicePacketSize = voicePacketSize + 96; 00052 00053 comfortNoisePacketSize = _pyco.get<Bit>("comfortNoisePacketSize"); 00054 /* Packet size includes 12 bytes RTP header. */ 00055 comfortNoisePacketSize = comfortNoisePacketSize + 96; 00056 00057 comfortNoise = _pyco.get<bool>("comfortNoise"); 00058 00059 MESSAGE_BEGIN(NORMAL, logger, m, "APPL: New VoIP session started with: "); 00060 m << "voicePacketSize = " << voicePacketSize; 00061 m << ", iat = " << iat; 00062 m << ", comfortNoisePacketSize = " << comfortNoisePacketSize; 00063 MESSAGE_END(); 00064 00065 maxDelay = _pyco.get<wns::simulator::Time>("maxDelay"); 00066 maxLossRatio = _pyco.get<double>("maxLossRatio"); 00067 00068 state = running; 00069 00070 /* only for probing */ 00071 sessionType = voip; 00072 00073 sessionDelay = (*sessionDelayDistribution)(); 00074 MESSAGE_SINGLE(NORMAL, logger, "APPL: Delay before session starts: " << sessionDelay << ".\n"); 00075 00076 setTimeout(connectiontimeout, sessionDelay); 00077 setTimeout(probetimeout, windowSize); 00078 } 00079 00080 00081 VoIP::~VoIP() 00082 { 00083 if (stateTransitionDistribution != NULL) 00084 delete stateTransitionDistribution; 00085 stateTransitionDistribution = NULL; 00086 } 00087 00088 00089 void 00090 VoIP::onData(const wns::osi::PDUPtr& _pdu) 00091 { 00092 assureType(_pdu.getPtr(), applications::session::PDU*); 00093 00094 receivedPacketNumber = static_cast<applications::session::PDU*>(_pdu.getPtr())->getPacketNumber(); 00095 00096 MESSAGE_SINGLE(NORMAL, logger, "APPL: receivedPacketNumber = " << receivedPacketNumber << "."); 00097 00098 applications::session::Session::incomingProbesCalculation(_pdu); 00099 00100 if((!receivedFirst) && (state != sessionended)) 00101 { 00102 receivedFirst = true; 00103 state = running; 00104 00105 onTimeout(sendtimeout); 00106 voIPState = active; 00107 setTimeout(statetransitiontimeout, 0.02); 00108 cancelTimeout(statetimeout); 00109 } 00110 } 00111 00112 00113 void 00114 VoIP::onTimeout(const Timeout& _t) 00115 { 00116 if(_t == sendtimeout) 00117 { 00118 MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending voicepacket!"); 00119 00120 applications::session::Session::iatProbesCalculation(); 00121 00122 packetSize = voicePacketSize; 00123 00124 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(voicePacketSize), pyco); 00125 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00126 00127 ++packetNumber; 00128 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00129 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00130 00131 wns::osi::PDUPtr pdu(applicationPDU); 00132 applications::session::Session::outgoingProbesCalculation(pdu); 00133 00134 connection->sendData(pdu); 00135 } 00136 else if(_t == receivetimeout) 00137 { 00138 /* Comfort noise packets will be send to fill the silence */ 00139 MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending comfort noise packet!"); 00140 00141 applications::session::Session::iatProbesCalculation(); 00142 00143 packetSize = comfortNoisePacketSize; 00144 00145 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(comfortNoisePacketSize), pyco); 00146 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00147 00148 ++packetNumber; 00149 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00150 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00151 00152 wns::osi::PDUPtr pdu(applicationPDU); 00153 00154 applications::session::Session::outgoingProbesCalculation(pdu); 00155 connection->sendData(pdu); 00156 } 00157 else if(_t == statetransitiontimeout) 00158 { 00159 /* Transition between active (speech) state and inactive (silent/pause) state. */ 00160 double stateTransitionValue = (*stateTransitionDistribution)(); 00161 00162 MESSAGE_SINGLE(NORMAL, logger, "APPL: State transition. TransitionValue = " << stateTransitionValue << "."); 00163 00164 if(stateTransitionValue <= 0.01 && voIPState == inactive) 00165 { 00166 cnCounter = 0; 00167 onTimeout(sendtimeout); 00168 00169 voIPState = active; 00170 } 00171 else if(stateTransitionValue > 0.01 && voIPState == inactive) 00172 { 00173 if(cnCounter == 8) 00174 { 00175 cnCounter = 1; 00176 onTimeout(receivetimeout); 00177 } 00178 else 00179 { 00180 cnCounter += 1; 00181 } 00182 } 00183 else if(stateTransitionValue <= 0.01 && voIPState == active) 00184 { 00185 cnCounter = 1; 00186 onTimeout(receivetimeout); 00187 00188 voIPState = inactive; 00189 } 00190 else if(stateTransitionValue > 0.01 && voIPState == active) 00191 { 00192 onTimeout(sendtimeout); 00193 } 00194 00195 setTimeout(statetransitiontimeout, 0.02); 00196 } 00197 else if(_t == connectiontimeout) 00198 { 00199 MESSAGE_SINGLE(NORMAL, logger, "APPL: Opening connection."); 00200 packetFrom = "client.VoIP"; 00201 00202 /* Open connection */ 00203 binding->initBinding(); 00204 } 00205 else if(_t == probetimeout) 00206 { 00207 applications::session::Session::onTimeout(_t); 00208 } 00209 else if(_t == statetimeout) 00210 { 00211 /* Start with calling the server. */ 00212 MESSAGE_SINGLE(NORMAL, logger, "APPL: Calling the server!"); 00213 00214 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(comfortNoisePacketSize), pyco); 00215 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00216 00217 packetSize = comfortNoisePacketSize; 00218 if(packetNumber < 1) 00219 packetNumber = 1; 00220 else 00221 packetNumber++; 00222 00223 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00224 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00225 00226 wns::osi::PDUPtr pdu(applicationPDU); 00227 00228 applications::session::Session::outgoingProbesCalculation(pdu); 00229 connection->sendData(pdu); 00230 00231 state = idle; 00232 00233 /* Retry after 0.5s if no answer from server */ 00234 /* ToDo: Should match server traffic start delay */ 00235 setTimeout(statetimeout, 0.5); 00236 } 00237 else 00238 { 00239 assure(false, "APPL: Unknown timout type =" << _t); 00240 } 00241 } 00242 00243 00244
1.5.5