/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
static const char* const SessionData_cxx_Version =
"$Id: SessionData.cxx,v 1.9 2001/03/23 19:19:08 wjin Exp $";
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "SessionData.hxx"
SessionData::SessionData()
: stack(0),
playFileFd( -1),
recFileFd( -1),
state(0),
pktSize(40)
{}
void
SessionData::receivePacket()
{
RtpPacket* packet = 0;
if (stack)
{
cout << "-";
packet = stack->receive();
}
if (packet)
{
if (recFileFd >= 0)
{
cout << "x";
if (packet->getPayloadUsage() != (8 * pktSize))
{
cout << "not the right size!" << endl;
}
write (recFileFd,
packet->getPayloadLoc(), packet->getPayloadUsage());
}
delete packet;
packet = 0;
}
else
{
cout << "no packet!" << endl;
}
}
void
SessionData::transmitPacket()
{
RtpPacket* packet = 0;
if (stack)
{
// packet = stack->createPacket(pktSize * 8);
packet = stack->createPacket();
if (playFileFd >= 0)
{
int bytecount =
read(playFileFd,
packet->getPayloadLoc(), packet->getPayloadSize());
if (bytecount)
{
packet->setPayloadUsage (bytecount);
// outRtpPkt->setRtpTime(audioStack->getPrevRtpTime() + NETWORK_RTP_RATE);
stack->transmit (packet);
}
else
{
// this file is now empty -- close and quit
close(playFileFd);
playFileFd = -1;
delete packet;
packet = 0;
if (state == 1)
{
// i'm done!
state = 2;
}
}
}
}
}
void SessionData::newStack(
const string& localPort,
const string& remoteHost,
const string& remotePort )
{
int localPortNumber = atoi(localPort.c_str());
int remotePortNumber = atoi(remotePort.c_str());
if ((localPortNumber < 1024) || (remotePortNumber < 1024))
{
return ;
}
closeStack();
stack = new RtpSession(remoteHost.c_str(), remotePortNumber,
localPortNumber, remotePortNumber + 1,
localPortNumber + 1, rtpPayloadPCMU,
rtpPayloadPCMU, 5);
stack->setApiPktSize (pktSize * 8);
stack->setNetworkPktSize (pktSize * 8);
// set SDES information - optional
RtcpTransmitter* rtcpTran = stack->getRtcpTran();
rtcpTran->setSdesEmail("development@vovida.com");
state = 0;
}
void
SessionData::addQueue(const string& str)
{
queueList.push_back(str);
}
void
SessionData::shouldUseQueue(bool val)
{
if (val)
{
if (state == 0)
{
state = 2;
}
}
else
{
state = 0;
}
}
void
SessionData::closeStack()
{
close(playFileFd);
close(recFileFd);
playFileFd = -1;
recFileFd = -1;
if (stack)
{
stack->transmitRTCPBYE();
delete stack;
}
state = 0;
stack = 0;
}
void
SessionData::setPktSize(int size)
{
pktSize = size;
}
void
SessionData::setPlayFile(const string& filename)
{
cout << "playing file: " << filename << endl;
if (playFileFd >= 0)
{
close(playFileFd);
}
// do something about this
int fd = open(filename.c_str(), O_RDONLY);
if (fd < 0)
{
cout << "error opening file for reading: " << filename << endl;
cout << "reason: " << strerror(errno) << endl;
// this is an error
}
playFileFd = fd;
}
void SessionData::stopRecord()
{
// stop recording
close(recFileFd);
recFileFd = -1;
}
void SessionData::setRecordFile(const string& filename)
{
cout << "record file: " << filename << endl;
if (recFileFd >= 0)
{
close(recFileFd);
}
// do something about this
int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR);
if (fd < 0)
{
cout << "error opening file for writing!" << endl;
cout << "reason: " << strerror(errno) << endl;
// this is an error
}
recFileFd = fd;
}
void
SessionData::handleQueue()
{
// do something about the queue items
if (state == 2)
{
if (queueList.size())
{
string cmd = (queueList.front());
queueList.pop_front();
state = 1;
// now, figure out what this means
if (cmd.length() >= 2)
{
if (cmd[0] == 'p')
{
// set the play buffer
setPlayFile(cmd.substr(2, cmd.length() - 2));
}
if (cmd[0] == 'r')
{
// set the record buffer
setRecordFile(cmd.substr(2, cmd.length() - 2));
}
}
}
else
{
// all done!
state = 0;
}
}
}
int SessionData::getFd()
{
if (stack)
{
return stack->getRtpRecv()->getSocketFD();
}
else
{
return -1;
}
}
void SessionData::periodicProcess()
{
VTime currentTime;
int deltaMs =
currentTime - lastTimePktSent;
if (deltaMs > (pktSize - 2))
{
// send a packet
transmitPacket();
lastTimePktSent = lastTimePktSent + pktSize;
}
if (state == 2)
{
handleQueue();
}
if (stack)
{
stack->processRTCP();
}
}
syntax highlighted by Code2HTML, v. 0.9.1