INET Framework for OMNeT++/OMNEST
inet::VoipStreamReceiver Class Reference

#include <VoipStreamReceiver.h>

Inheritance diagram for inet::VoipStreamReceiver:
inet::LifecycleUnsupported inet::UdpSocket::ICallback inet::ILifecycle

Classes

class  Connection
 

Public Member Functions

 VoipStreamReceiver ()
 
 ~VoipStreamReceiver ()
 
- Public Member Functions inherited from inet::LifecycleUnsupported
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::UdpSocket::ICallback
virtual ~ICallback ()
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void finish () override
 
virtual void createConnection (Packet *vp)
 
virtual void checkSourceAndParameters (Packet *vp)
 
virtual void closeConnection ()
 
virtual void decodePacket (Packet *vp)
 
virtual void socketDataArrived (UdpSocket *socket, Packet *packet) override
 Notifies about data arrival, packet ownership is transferred to the callee. More...
 
virtual void socketErrorArrived (UdpSocket *socket, Indication *indication) override
 Notifies about error indication arrival, indication ownership is transferred to the callee. More...
 
virtual void socketClosed (UdpSocket *socket) override
 Notifies about socket closed, indication ownership is transferred to the callee. More...
 

Protected Attributes

int localPort = -1
 
simtime_t playoutDelay
 
const char * resultFile = nullptr
 
UdpSocket socket
 
Connection curConn
 

Static Protected Attributes

static simsignal_t lostSamplesSignal = registerSignal("lostSamples")
 
static simsignal_t lostPacketsSignal = registerSignal("lostPackets")
 
static simsignal_t packetHasVoiceSignal = registerSignal("packetHasVoice")
 
static simsignal_t connStateSignal = registerSignal("connState")
 
static simsignal_t delaySignal = registerSignal("delay")
 

Constructor & Destructor Documentation

◆ VoipStreamReceiver()

inet::VoipStreamReceiver::VoipStreamReceiver ( )
inline
40 {}

◆ ~VoipStreamReceiver()

inet::VoipStreamReceiver::~VoipStreamReceiver ( )
33 {
35 }

Member Function Documentation

◆ checkSourceAndParameters()

void inet::VoipStreamReceiver::checkSourceAndParameters ( Packet vp)
protectedvirtual
194 {
195  ASSERT(!curConn.offline);
196 
197  const auto& vp = pk->peekAtFront<VoipStreamPacket>();
198  auto l3Addresses = pk->getTag<L3AddressInd>();
199  auto ports = pk->getTag<L4PortInd>();
200  L3Address srcAddr = l3Addresses->getSrcAddress();
201  L3Address destAddr = l3Addresses->getDestAddress();
202 
203  if (curConn.srcAddr != srcAddr
204  || curConn.srcPort != ports->getSrcPort()
205  || curConn.destAddr != destAddr
206  || curConn.destPort != ports->getDestPort()
207  || vp->getSsrc() != curConn.ssrc)
208  throw cRuntimeError("Voice packet received from third party during a voice session (concurrent voice sessions not supported)");
209 
210  if (vp->getCodec() != curConn.codec
211  || vp->getSampleBits() != curConn.sampleBits
212  || vp->getSampleRate() != curConn.sampleRate
213  || vp->getSamplesPerPacket() != curConn.samplesPerPacket
214  || vp->getTransmitBitrate() != curConn.transmitBitrate)
215  throw cRuntimeError("Cannot change voice encoding parameters a during session");
216 }

Referenced by socketDataArrived().

◆ closeConnection()

void inet::VoipStreamReceiver::closeConnection ( )
protectedvirtual
219 {
220  if (!curConn.offline) {
221  curConn.offline = true;
222  avcodec_close(curConn.decCtx);
223  avcodec_free_context(&curConn.decCtx);
225  emit(connStateSignal, -1L); // so that sum() yields the number of active sessions
226  }
227 }

Referenced by finish(), and ~VoipStreamReceiver().

◆ createConnection()

void inet::VoipStreamReceiver::createConnection ( Packet vp)
protectedvirtual
153 {
154  ASSERT(curConn.offline);
155 
156  const auto& vp = pk->peekAtFront<VoipStreamPacket>();
157  auto l3Addresses = pk->getTag<L3AddressInd>();
158  auto ports = pk->getTag<L4PortInd>();
159 
160  curConn.srcAddr = l3Addresses->getSrcAddress();
161  curConn.srcPort = ports->getSrcPort();
162  curConn.destAddr = l3Addresses->getDestAddress();
163  curConn.destPort = ports->getDestPort();
164  curConn.seqNo = vp->getSeqNo() - 1;
165  curConn.timeStamp = vp->getTimeStamp();
166  curConn.ssrc = vp->getSsrc();
167  curConn.codec = (enum AVCodecID)(vp->getCodec());
168  curConn.sampleBits = vp->getSampleBits();
169  curConn.sampleRate = vp->getSampleRate();
170  curConn.transmitBitrate = vp->getTransmitBitrate();
171  curConn.samplesPerPacket = vp->getSamplesPerPacket();
172  curConn.lastPacketFinish = simTime() + playoutDelay;
173 
174  curConn.pCodecDec = avcodec_find_decoder(curConn.codec);
175  if (curConn.pCodecDec == nullptr)
176  throw cRuntimeError("Codec %d not found", curConn.codec);
177 
178  curConn.decCtx = avcodec_alloc_context3(curConn.pCodecDec);
180  curConn.decCtx->sample_rate = curConn.sampleRate;
181  curConn.decCtx->channels = 1;
182  curConn.decCtx->bits_per_coded_sample = curConn.sampleBits;
183 
184  int ret = avcodec_open2(curConn.decCtx, curConn.pCodecDec, nullptr);
185  if (ret < 0)
186  throw cRuntimeError("could not open decoding codec %d (%s): err=%d", curConn.codec, curConn.pCodecDec->name, ret);
187 
189  curConn.offline = false;
190  emit(connStateSignal, 1);
191 }

Referenced by socketDataArrived().

◆ decodePacket()

void inet::VoipStreamReceiver::decodePacket ( Packet vp)
protectedvirtual
230 {
231  const auto& vp = pk->popAtFront<VoipStreamPacket>();
232  uint16_t newSeqNo = vp->getSeqNo();
233  if (newSeqNo > curConn.seqNo + 1)
234  emit(lostPacketsSignal, newSeqNo - (curConn.seqNo + 1));
235 
236  if (simTime() > curConn.lastPacketFinish) {
237  int lostSamples = ceil(SIMTIME_DBL((simTime() - curConn.lastPacketFinish) * curConn.sampleRate));
238  ASSERT(lostSamples > 0);
239  EV_INFO << "Lost " << lostSamples << " samples\n";
240  emit(lostSamplesSignal, lostSamples);
241  curConn.writeLostSamples(lostSamples);
242  curConn.lastPacketFinish += lostSamples * (1.0 / curConn.sampleRate);
243  FINGERPRINT_ADD_EXTRA_DATA(lostSamples);
244  }
245  emit(delaySignal, curConn.lastPacketFinish - pk->getCreationTime());
246  curConn.seqNo = newSeqNo;
247 
248  if (vp->getType() == VOICE) {
249  emit(packetHasVoiceSignal, 1);
250  uint16_t len = vp->getDataLength();
251  auto bb = pk->peekDataAt<BytesChunk>(b(0), B(len));
252  auto buff = bb->getBytes();
253  curConn.writeAudioFrame(&buff.front(), buff.size());
254  FINGERPRINT_ADD_EXTRA_DATA2((const char *)(&buff.front()), buff.size());
255  }
256  else if (vp->getType() == SILENCE) {
257  emit(packetHasVoiceSignal, 0);
258  int silenceSamples = vp->getSamplesPerPacket();
259  curConn.writeLostSamples(silenceSamples);
260  curConn.lastPacketFinish += silenceSamples * (1.0 / curConn.sampleRate);
261  FINGERPRINT_ADD_EXTRA_DATA(silenceSamples);
262  }
263  else
264  throw cRuntimeError("The received VoipStreamPacket has unknown type %d", vp->getType());
265 }

Referenced by socketDataArrived().

◆ finish()

void inet::VoipStreamReceiver::finish ( )
overrideprotectedvirtual
268 {
269  EV_TRACE << "Sink finish()" << endl;
270  closeConnection();
271 }

◆ handleMessage()

void inet::VoipStreamReceiver::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
70 {
71  if (msg->arrivedOn("socketIn")) {
73  }
74  else
75  throw cRuntimeError("Unknown incoming gate: '%s'", msg->getArrivalGate()->getFullName());
76 }

◆ initialize()

void inet::VoipStreamReceiver::initialize ( int  stage)
overrideprotectedvirtual
38 {
39  cSimpleModule::initialize(stage);
40 
41  if (stage == INITSTAGE_LOCAL) {
42  // KLUDGE hack to create results folder (doesn't work when record-scalars = false)
43  recordScalar("hackForCreateResultsFolder", 0);
44 
45  // Say Hello to the world
46  EV_TRACE << "VoIPSinkApp initialize()" << endl;
47 
48  // read parameters
49  localPort = par("localPort");
50  resultFile = par("resultFile");
51  playoutDelay = par("playoutDelay");
52 
53  // initialize avcodec library
54  av_register_all();
55  }
56  else if (stage == INITSTAGE_APPLICATION_LAYER) {
57  cModule *node = findContainingNode(this);
58  NodeStatus *nodeStatus = node ? check_and_cast_nullable<NodeStatus *>(node->getSubmodule("status")) : nullptr;
59  bool isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
60  if (!isOperational)
61  throw cRuntimeError("This module doesn't support starting in node DOWN state");
62 
63  socket.setOutputGate(gate("socketOut"));
65  socket.setCallback(this);
66  }
67 }

◆ numInitStages()

virtual int inet::VoipStreamReceiver::numInitStages ( ) const
inlineoverrideprotectedvirtual
45 { return NUM_INIT_STAGES; }

◆ socketClosed()

virtual void inet::VoipStreamReceiver::socketClosed ( UdpSocket socket)
inlineoverrideprotectedvirtual

Notifies about socket closed, indication ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

57 {}

◆ socketDataArrived()

void inet::VoipStreamReceiver::socketDataArrived ( UdpSocket socket,
Packet packet 
)
overrideprotectedvirtual

Notifies about data arrival, packet ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

79 {
80  // process incoming packet
81 
82  const auto& vp = pk->peekAtFront<VoipStreamPacket>();
83  bool ok = true;
84  if (curConn.offline)
85  createConnection(pk);
86  else {
88  ok = vp->getSeqNo() > curConn.seqNo && vp->getTimeStamp() > curConn.timeStamp;
89  }
90 
91  if (ok) {
92  emit(packetReceivedSignal, pk);
93  decodePacket(pk);
94  }
95  else {
96  PacketDropDetails details;
97  details.setReason(CONGESTION);
98  emit(packetDroppedSignal, pk, &details);
99  }
100 
101  delete pk;
102 }

◆ socketErrorArrived()

void inet::VoipStreamReceiver::socketErrorArrived ( UdpSocket socket,
Indication indication 
)
overrideprotectedvirtual

Notifies about error indication arrival, indication ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

105 {
106  EV_WARN << "Unknown message '" << indication->getName() << "', kind = " << indication->getKind() << ", discarding it." << endl;
107  delete indication;
108 }

Member Data Documentation

◆ connStateSignal

simsignal_t inet::VoipStreamReceiver::connStateSignal = registerSignal("connState")
staticprotected

◆ curConn

Connection inet::VoipStreamReceiver::curConn
protected

◆ delaySignal

simsignal_t inet::VoipStreamReceiver::delaySignal = registerSignal("delay")
staticprotected

Referenced by decodePacket().

◆ localPort

int inet::VoipStreamReceiver::localPort = -1
protected

Referenced by initialize().

◆ lostPacketsSignal

simsignal_t inet::VoipStreamReceiver::lostPacketsSignal = registerSignal("lostPackets")
staticprotected

Referenced by decodePacket().

◆ lostSamplesSignal

simsignal_t inet::VoipStreamReceiver::lostSamplesSignal = registerSignal("lostSamples")
staticprotected

Referenced by decodePacket().

◆ packetHasVoiceSignal

simsignal_t inet::VoipStreamReceiver::packetHasVoiceSignal = registerSignal("packetHasVoice")
staticprotected

Referenced by decodePacket().

◆ playoutDelay

simtime_t inet::VoipStreamReceiver::playoutDelay
protected

Referenced by createConnection(), and initialize().

◆ resultFile

const char* inet::VoipStreamReceiver::resultFile = nullptr
protected

Referenced by createConnection(), and initialize().

◆ socket

UdpSocket inet::VoipStreamReceiver::socket
protected

Referenced by handleMessage(), and initialize().


The documentation for this class was generated from the following files:
inet::UdpSocket::setOutputGate
void setOutputGate(cGate *toUdp)
Sets the gate on which to send to UDP.
Definition: UdpSocket.h:117
inet::VoipStreamReceiver::Connection::samplesPerPacket
int samplesPerPacket
Definition: VoipStreamReceiver.h:76
inet::findContainingNode
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
inet::VoipStreamReceiver::Connection::pCodecDec
AVCodec * pCodecDec
Definition: VoipStreamReceiver.h:83
inet::UdpSocket::bind
void bind(int localPort)
Bind the socket to a local port number.
Definition: UdpSocket.cc:34
inet::VoipStreamReceiver::Connection::transmitBitrate
int transmitBitrate
Definition: VoipStreamReceiver.h:77
inet::VoipStreamReceiver::Connection::writeLostSamples
void writeLostSamples(int sampleCount)
Definition: VoipStreamReceiver.cc:115
inet::VoipStreamReceiver::resultFile
const char * resultFile
Definition: VoipStreamReceiver.h:94
inet::VoipStreamReceiver::Connection::openAudio
void openAudio(const char *fileName)
Definition: VoipStreamReceiver.cc:110
inet::VoipStreamReceiver::Connection::sampleBits
short sampleBits
Definition: VoipStreamReceiver.h:74
inet::VoipStreamReceiver::Connection::offline
bool offline
Definition: VoipStreamReceiver.h:69
inet::VoipStreamReceiver::Connection::ssrc
uint32_t ssrc
Definition: VoipStreamReceiver.h:72
inet::VoipStreamReceiver::Connection::destPort
int destPort
Definition: VoipStreamReceiver.h:88
inet::VoipStreamReceiver::Connection::timeStamp
uint32_t timeStamp
Definition: VoipStreamReceiver.h:71
inet::VoipStreamReceiver::Connection::writeAudioFrame
void writeAudioFrame(uint8_t *buf, int len)
Definition: VoipStreamReceiver.cc:125
inet::VoipStreamReceiver::curConn
Connection curConn
Definition: VoipStreamReceiver.h:98
inet::VoipStreamReceiver::Connection::seqNo
uint16_t seqNo
Definition: VoipStreamReceiver.h:70
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::UdpSocket::setCallback
void setCallback(ICallback *cb)
Sets a callback object, to be used with processMessage().
Definition: UdpSocket.cc:338
inet::packetDroppedSignal
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
inet::VoipStreamReceiver::closeConnection
virtual void closeConnection()
Definition: VoipStreamReceiver.cc:218
inet::VoipStreamReceiver::Connection::codec
enum AVCodecID codec
Definition: VoipStreamReceiver.h:73
inet::VoipStreamReceiver::delaySignal
static simsignal_t delaySignal
Definition: VoipStreamReceiver.h:104
inet::VoipStreamReceiver::Connection::sampleRate
int sampleRate
Definition: VoipStreamReceiver.h:75
inet::VoipStreamReceiver::lostPacketsSignal
static simsignal_t lostPacketsSignal
Definition: VoipStreamReceiver.h:101
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::VoipStreamReceiver::Connection::decCtx
AVCodecContext * decCtx
Definition: VoipStreamReceiver.h:82
inet::VoipStreamReceiver::checkSourceAndParameters
virtual void checkSourceAndParameters(Packet *vp)
Definition: VoipStreamReceiver.cc:193
inet::packetReceivedSignal
simsignal_t packetReceivedSignal
Definition: Simsignals.cc:97
inet::VoipStreamReceiver::Connection::lastPacketFinish
simtime_t lastPacketFinish
Definition: VoipStreamReceiver.h:78
inet::UdpSocket::processMessage
virtual void processMessage(cMessage *msg) override
Examines the message, takes ownership, and updates socket state.
Definition: UdpSocket.cc:343
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::VoipStreamReceiver::playoutDelay
simtime_t playoutDelay
Definition: VoipStreamReceiver.h:93
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::VoipStreamReceiver::socket
UdpSocket socket
Definition: VoipStreamReceiver.h:96
inet::VoipStreamReceiver::createConnection
virtual void createConnection(Packet *vp)
Definition: VoipStreamReceiver.cc:152
inet::AudioOutFile::close
bool close()
Definition: AudioOutFile.cc:139
inet::VoipStreamReceiver::connStateSignal
static simsignal_t connStateSignal
Definition: VoipStreamReceiver.h:103
L4PortInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L4PortInd
Definition: IUdp-gates.txt:20
inet::INITSTAGE_APPLICATION_LAYER
INET_API InitStage INITSTAGE_APPLICATION_LAYER
Initialization of applications.
FINGERPRINT_ADD_EXTRA_DATA2
#define FINGERPRINT_ADD_EXTRA_DATA2(x, y)
Definition: INETDefs.h:85
inet::NodeStatus::UP
@ UP
Definition: NodeStatus.h:28
inet::VoipStreamReceiver::Connection::destAddr
L3Address destAddr
Definition: VoipStreamReceiver.h:87
FINGERPRINT_ADD_EXTRA_DATA
#define FINGERPRINT_ADD_EXTRA_DATA(x)
Definition: INETDefs.h:84
inet::CONGESTION
@ CONGESTION
Definition: Simsignals_m.h:80
inet::VoipStreamReceiver::decodePacket
virtual void decodePacket(Packet *vp)
Definition: VoipStreamReceiver.cc:229
inet::VoipStreamReceiver::localPort
int localPort
Definition: VoipStreamReceiver.h:92
inet::VoipStreamReceiver::packetHasVoiceSignal
static simsignal_t packetHasVoiceSignal
Definition: VoipStreamReceiver.h:102
inet::VoipStreamReceiver::Connection::srcPort
int srcPort
Definition: VoipStreamReceiver.h:86
inet::VoipStreamReceiver::Connection::outFile
AudioOutFile outFile
Definition: VoipStreamReceiver.h:84
inet::VoipStreamReceiver::lostSamplesSignal
static simsignal_t lostSamplesSignal
Definition: VoipStreamReceiver.h:100
inet::VoipStreamReceiver::Connection::srcAddr
L3Address srcAddr
Definition: VoipStreamReceiver.h:85