no message
git-svn-id: http://yate.null.ro/svn/yate/trunk@378 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
3f261fc812
commit
d6b03a2919
|
@ -232,7 +232,9 @@ void* DataSource::getObject(const String& name) const
|
|||
}
|
||||
|
||||
DataEndpoint::DataEndpoint(CallEndpoint* call, const char* name)
|
||||
: m_name(name), m_source(0), m_consumer(0), m_peer(0), m_call(call)
|
||||
: m_name(name), m_source(0), m_consumer(0),
|
||||
m_peer(0), m_call(call),
|
||||
m_peerRecord(0), m_callRecord(0)
|
||||
{
|
||||
Debug(DebugInfo,"DataEndpoint::DataEndpoint(%p,'%s') [%p]",call,name,this);
|
||||
if (m_call)
|
||||
|
@ -246,6 +248,8 @@ DataEndpoint::~DataEndpoint()
|
|||
if (m_call)
|
||||
m_call->m_data.remove(this,false);
|
||||
disconnect();
|
||||
setPeerRecord();
|
||||
setCallRecord();
|
||||
setSource();
|
||||
setConsumer();
|
||||
}
|
||||
|
@ -281,6 +285,9 @@ bool DataEndpoint::connect(DataEndpoint* peer)
|
|||
if (!native) {
|
||||
DataSource *s = getSource();
|
||||
DataConsumer *c = peer->getConsumer();
|
||||
if (s && c)
|
||||
DataTranslator::attachChain(s,c);
|
||||
c = peer->getPeerRecord();
|
||||
if (s && c)
|
||||
DataTranslator::attachChain(s,c);
|
||||
|
||||
|
@ -288,6 +295,9 @@ bool DataEndpoint::connect(DataEndpoint* peer)
|
|||
c = getConsumer();
|
||||
if (s && c)
|
||||
DataTranslator::attachChain(s,c);
|
||||
c = getPeerRecord();
|
||||
if (s && c)
|
||||
DataTranslator::attachChain(s,c);
|
||||
}
|
||||
|
||||
m_peer = peer;
|
||||
|
@ -304,11 +314,17 @@ void DataEndpoint::disconnect()
|
|||
|
||||
DataSource *s = getSource();
|
||||
DataConsumer *c = m_peer->getConsumer();
|
||||
if (s && c)
|
||||
DataTranslator::detachChain(s,c);
|
||||
c = m_peer->getPeerRecord();
|
||||
if (s && c)
|
||||
DataTranslator::detachChain(s,c);
|
||||
|
||||
s = m_peer->getSource();
|
||||
c = getConsumer();
|
||||
if (s && c)
|
||||
DataTranslator::detachChain(s,c);
|
||||
c = getPeerRecord();
|
||||
if (s && c)
|
||||
DataTranslator::detachChain(s,c);
|
||||
|
||||
|
@ -323,27 +339,50 @@ void DataEndpoint::setSource(DataSource* source)
|
|||
{
|
||||
if (source == m_source)
|
||||
return;
|
||||
DataConsumer *consumer = m_peer ? m_peer->getConsumer() : 0;
|
||||
DataConsumer *c1 = m_peer ? m_peer->getConsumer() : 0;
|
||||
DataConsumer *c2 = m_peer ? m_peer->getPeerRecord() : 0;
|
||||
DataSource *temp = m_source;
|
||||
if (consumer)
|
||||
consumer->ref();
|
||||
if (c1)
|
||||
c1->ref();
|
||||
if (c2)
|
||||
c2->ref();
|
||||
if (m_callRecord)
|
||||
m_callRecord->ref();
|
||||
m_source = 0;
|
||||
if (temp) {
|
||||
if (consumer) {
|
||||
DataTranslator::detachChain(temp,consumer);
|
||||
if (consumer->getConnSource())
|
||||
Debug(DebugWarn,"consumer source not cleared in %p",consumer);
|
||||
if (c1) {
|
||||
DataTranslator::detachChain(temp,c1);
|
||||
if (c1->getConnSource())
|
||||
Debug(DebugWarn,"consumer source not cleared in %p",c1);
|
||||
}
|
||||
if (c2) {
|
||||
DataTranslator::detachChain(temp,c2);
|
||||
if (c2->getConnSource())
|
||||
Debug(DebugWarn,"consumer source not cleared in %p",c2);
|
||||
}
|
||||
if (m_callRecord) {
|
||||
DataTranslator::detachChain(temp,m_callRecord);
|
||||
if (m_callRecord->getConnSource())
|
||||
Debug(DebugWarn,"consumer source not cleared in %p",m_callRecord);
|
||||
}
|
||||
temp->deref();
|
||||
}
|
||||
if (source) {
|
||||
source->ref();
|
||||
if (consumer)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
if (c1)
|
||||
DataTranslator::attachChain(source,c1);
|
||||
if (c2)
|
||||
DataTranslator::attachChain(source,c2);
|
||||
if (m_callRecord)
|
||||
DataTranslator::attachChain(source,m_callRecord);
|
||||
}
|
||||
m_source = source;
|
||||
if (consumer)
|
||||
consumer->deref();
|
||||
if (c1)
|
||||
c1->deref();
|
||||
if (c2)
|
||||
c2->deref();
|
||||
if (m_callRecord)
|
||||
m_callRecord->deref();
|
||||
}
|
||||
|
||||
void DataEndpoint::setConsumer(DataConsumer* consumer)
|
||||
|
@ -365,6 +404,43 @@ void DataEndpoint::setConsumer(DataConsumer* consumer)
|
|||
}
|
||||
}
|
||||
|
||||
void DataEndpoint::setPeerRecord(DataConsumer* consumer)
|
||||
{
|
||||
if (consumer == m_peerRecord)
|
||||
return;
|
||||
DataSource *source = m_peer ? m_peer->getSource() : 0;
|
||||
DataConsumer *temp = m_peerRecord;
|
||||
if (consumer) {
|
||||
consumer->ref();
|
||||
if (source)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
}
|
||||
m_peerRecord = consumer;
|
||||
if (temp) {
|
||||
if (source)
|
||||
DataTranslator::detachChain(source,temp);
|
||||
temp->deref();
|
||||
}
|
||||
}
|
||||
|
||||
void DataEndpoint::setCallRecord(DataConsumer* consumer)
|
||||
{
|
||||
if (consumer == m_callRecord)
|
||||
return;
|
||||
DataConsumer *temp = m_callRecord;
|
||||
if (consumer) {
|
||||
consumer->ref();
|
||||
if (m_source)
|
||||
DataTranslator::attachChain(m_source,consumer);
|
||||
}
|
||||
m_callRecord = consumer;
|
||||
if (temp) {
|
||||
if (m_source)
|
||||
DataTranslator::detachChain(m_source,temp);
|
||||
temp->deref();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadedSource::~ThreadedSource()
|
||||
{
|
||||
stop();
|
||||
|
|
|
@ -310,22 +310,19 @@ void ThreadPrivate::killall()
|
|||
while (l && (t = static_cast<ThreadPrivate *>(l->get())) != 0)
|
||||
{
|
||||
Debug(DebugInfo,"Trying to kill ThreadPrivate '%s' [%p], attempt %d",t->m_name,t,c);
|
||||
tmutex.unlock();
|
||||
bool ok = t->cancel(c > SOFT_KILLS);
|
||||
if (ok) {
|
||||
int d = 0;
|
||||
// delay a little (exponentially) so threads have a chance to clean up
|
||||
for (int i=1; i<=KILL_WAIT; i<<=1) {
|
||||
tmutex.unlock();
|
||||
Thread::msleep(i-d);
|
||||
d = i;
|
||||
tmutex.lock();
|
||||
bool done = (t != l->get());
|
||||
tmutex.unlock();
|
||||
if (done)
|
||||
if (t != l->get())
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmutex.lock();
|
||||
if (t != l->get())
|
||||
c = 1;
|
||||
else {
|
||||
|
|
|
@ -97,6 +97,13 @@ public:
|
|||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class RecordHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
RecordHandler() : MessageHandler("chan.record") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class WaveFileDriver : public Driver
|
||||
{
|
||||
public:
|
||||
|
@ -430,6 +437,87 @@ bool AttachHandler::received(Message &msg)
|
|||
return !more;
|
||||
}
|
||||
|
||||
bool RecordHandler::received(Message &msg)
|
||||
{
|
||||
int more = 2;
|
||||
|
||||
String c1(msg.getValue("call"));
|
||||
if (c1.null())
|
||||
more--;
|
||||
else {
|
||||
Regexp r("^wave/\\([^/]*\\)/\\(.*\\)$");
|
||||
if (c1.matches(r)) {
|
||||
if (c1.matchString(1) == "record") {
|
||||
c1 = c1.matchString(2);
|
||||
more--;
|
||||
}
|
||||
else {
|
||||
Debug(DebugWarn,"Could not attach call recorder with method '%s', use 'record'",
|
||||
c1.matchString(1).c_str());
|
||||
c1 = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
c1 = "";
|
||||
}
|
||||
|
||||
String c2(msg.getValue("peer"));
|
||||
if (c2.null())
|
||||
more--;
|
||||
else {
|
||||
Regexp r("^wave/\\([^/]*\\)/\\(.*\\)$");
|
||||
if (c2.matches(r)) {
|
||||
if (c2.matchString(1) == "record") {
|
||||
c2 = c2.matchString(2);
|
||||
more--;
|
||||
}
|
||||
else {
|
||||
Debug(DebugWarn,"Could not attach peer recorder with method '%s', use 'record'",
|
||||
c2.matchString(1).c_str());
|
||||
c2 = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
c2 = "";
|
||||
}
|
||||
|
||||
if (c1.null() && c2.null())
|
||||
return false;
|
||||
|
||||
String ml(msg.getValue("maxlen"));
|
||||
unsigned maxlen = ml.toInteger(0);
|
||||
|
||||
CallEndpoint *ch = static_cast<CallEndpoint*>(msg.userData("CallEndpoint"));
|
||||
DataEndpoint *de = static_cast<DataEndpoint*>(msg.userData("DataEndpoint"));
|
||||
if (ch && !de)
|
||||
de = ch->setEndpoint();
|
||||
|
||||
if (!de) {
|
||||
if (!c1.null())
|
||||
Debug(DebugWarn,"Wave source '%s' call record with no data channel!",c1.c_str());
|
||||
if (!c2.null())
|
||||
Debug(DebugWarn,"Wave source '%s' peer record with no data channel!",c2.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!c1.null()) {
|
||||
WaveConsumer* c = new WaveConsumer(c1,ch,maxlen);
|
||||
c->setNotify(msg.getValue("notify"));
|
||||
de->setCallRecord(c);
|
||||
c->deref();
|
||||
}
|
||||
|
||||
if (!c2.null()) {
|
||||
WaveConsumer* c = new WaveConsumer(c2,ch,maxlen);
|
||||
c->setNotify(msg.getValue("notify"));
|
||||
de->setPeerRecord(c);
|
||||
c->deref();
|
||||
}
|
||||
|
||||
// Stop dispatching if we handled all requested
|
||||
return !more;
|
||||
}
|
||||
|
||||
bool WaveFileDriver::msgExecute(Message& msg, String& dest)
|
||||
{
|
||||
Regexp r("^\\([^/]*\\)/\\(.*\\)$");
|
||||
|
@ -509,6 +597,7 @@ void WaveFileDriver::initialize()
|
|||
if (!m_handler) {
|
||||
m_handler = new AttachHandler;
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new RecordHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -235,6 +235,14 @@ public:
|
|||
inline RefObject* userData() const
|
||||
{ return m_data; }
|
||||
|
||||
/**
|
||||
* Get a pointer to a derived class of user data given that class name
|
||||
* @param name Name of the class we are asking for
|
||||
* @return Pointer to the requested class or NULL if user object id NULL or doesn't implement it
|
||||
*/
|
||||
inline void* userData(const String& name) const
|
||||
{ return m_data ? m_data->getObject(name) : 0; }
|
||||
|
||||
/**
|
||||
* Set obscure data associated with the message.
|
||||
* The user data is reference counted to avoid stray pointers.
|
||||
|
|
30
yatephone.h
30
yatephone.h
|
@ -669,6 +669,34 @@ public:
|
|||
inline DataConsumer* getConsumer() const
|
||||
{ return m_consumer; }
|
||||
|
||||
/**
|
||||
* Set the data consumer for recording peer generated data.
|
||||
* This will be connected to the peer data source.
|
||||
* @param consumer A pointer to the new consumer or NULL
|
||||
*/
|
||||
void setPeerRecord(DataConsumer* consumer = 0);
|
||||
|
||||
/**
|
||||
* Get the data consumer used for recording peer generated data.
|
||||
* @return A pointer to the DataConsumer object or NULL
|
||||
*/
|
||||
inline DataConsumer* getPeerRecord() const
|
||||
{ return m_peerRecord; }
|
||||
|
||||
/**
|
||||
* Set the data consumer for recording local call generated data
|
||||
* This will be connected to the local data source.
|
||||
* @param consumer A pointer to the new consumer or NULL
|
||||
*/
|
||||
void setCallRecord(DataConsumer* consumer = 0);
|
||||
|
||||
/**
|
||||
* Get the data consumer used for recording local call generated data.
|
||||
* @return A pointer to the DataConsumer object or NULL
|
||||
*/
|
||||
inline DataConsumer* getCallRecord() const
|
||||
{ return m_callRecord; }
|
||||
|
||||
/*
|
||||
* Get a pointer to the peer endpoint
|
||||
* @return A pointer to the peer endpoint or NULL
|
||||
|
@ -705,6 +733,8 @@ private:
|
|||
DataConsumer* m_consumer;
|
||||
DataEndpoint* m_peer;
|
||||
CallEndpoint* m_call;
|
||||
DataConsumer* m_peerRecord;
|
||||
DataConsumer* m_callRecord;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue