Fixed a bug when compiling with gcc-4.2+. Better handling of session

connects. Reworded many debug messages and moved them to debug compiles.


git-svn-id: http://voip.null.ro/svn/yate@1084 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2006-10-20 19:40:38 +00:00
parent 0eae1637d9
commit 0831be8c62
10 changed files with 259 additions and 266 deletions

View File

@ -558,15 +558,15 @@ JBClient::~JBClient()
/**
* JBPresence
*/
const char* JBPresence::s_presence[] = {
"error",
"probe",
"subscribe",
"subscribed",
"unavailable",
"unsubscribe",
"unsubscribed",
"\0",
TokenDict JBPresence::s_presence[] = {
{"error", Error},
{"probe", Probe},
{"subscribe", Subscribe},
{"subscribed", Subscribed},
{"unavailable", Unavailable},
{"unsubscribe", Unsubscribe},
{"unsubscribed", Unsubscribed},
{0,0}
};
JBPresence::JBPresence(JBEngine* engine)
@ -594,7 +594,6 @@ bool JBPresence::receive(JBEvent* event)
// Check destination's server name
// Reject not owned
if (!event)
return false;
switch (event->type()) {
@ -673,7 +672,7 @@ void JBPresence::runProcess()
#define show(method,e) \
{ \
DDebug(this,DebugAll, \
"%s. Event: (%p). From: '%s' To: '%s'.", \
"JBPresence::%s. Event: (%p). From: '%s' To: '%s'.", \
method,e,e->from().c_str(),e->to().c_str()); \
}
@ -726,7 +725,7 @@ XMLElement* JBPresence::createPresence(const char* from,
const char* to, Presence type)
{
XMLElement* presence = new XMLElement(XMLElement::Presence);
presence->setAttributeValid("type",type < None ? s_presence[type] : "");
presence->setAttributeValid("type",presenceText(type));
presence->setAttribute("from",from);
presence->setAttribute("to",to);
return presence;
@ -751,19 +750,4 @@ bool JBPresence::decodeError(const XMLElement* element,
return true;
}
JBPresence::Presence JBPresence::presenceType(const char* txt)
{
if (!txt)
return None;
for (u_int16_t i = 0; i < None; i++)
if (s_presence[i] && 0 == strcmp(txt,s_presence[i]))
return (Presence)i;
return None;
}
const char* JBPresence::presenceText(JBPresence::Presence presence)
{
return ((presence < None) ? s_presence[presence] : 0);
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -30,6 +30,15 @@ static XMPPError s_err;
static const char* s_declaration = "<?xml version='1.0' encoding='UTF-8'?>";
// Just a shorter code
inline XMLElement* errorHostGone()
{
return XMPPUtils::createStreamError(XMPPError::HostGone);
}
/**
* JBComponentStream
*/
JBComponentStream::JBComponentStream(JBEngine* engine, const String& remoteName,
const SocketAddr& remoteAddr)
: Mutex(true),
@ -45,7 +54,7 @@ JBComponentStream::JBComponentStream(JBEngine* engine, const String& remoteName,
m_totalRestart(-1),
m_waitBeforeConnect(false)
{
Debug(m_engine,DebugAll,"JBComponentStream [%p].",this);
Debug(m_engine,DebugAll,"JBComponentStream. [%p]",this);
if (!engine)
return;
// Init data
@ -58,22 +67,20 @@ JBComponentStream::JBComponentStream(JBEngine* engine, const String& remoteName,
JBComponentStream::~JBComponentStream()
{
Debug(m_engine,DebugAll,"~JBComponentStream [%p].",this);
Debug(m_engine,DebugAll,"~JBComponentStream. [%p]",this);
if (m_engine->debugAt(DebugAll)) {
String buf;
m_parser.getBuffer(buf);
Debug(m_engine,DebugAll,"Stream. Incoming XML parser buffer: '%s'. Elements: [%p]",
buf.c_str(),this);
for (u_int32_t i = 0; true; i++) {
String buffer, element;
for (; true; ) {
XMLElement* e = m_parser.extract();
if (!e)
break;
buf.clear();
XMPPUtils::print(buf,e);
Debug(m_engine,DebugAll,"Stream. Incoming XML element %u [%p]%s.",
i+1,this,buf.c_str());
XMPPUtils::print(element,e);
delete e;
}
m_parser.getBuffer(buffer);
Debug(m_engine,DebugAll,
"Stream. Incoming data:[%p]\r\nParser buffer: '%s'.\r\nParsed elements: %s",
this,buffer.c_str(),element?element.c_str():"None.");
}
cleanup(false,0);
m_engine->removeStream(this,false);
@ -109,13 +116,13 @@ void JBComponentStream::connect()
lock.lock(*this,m_receiveMutex);
if (!res) {
Debug(m_engine,DebugWarn,
"Stream::connect. Failed to connect socket to '%s' (Port: %d). Error: '%s' (%d). [%p]",
"Stream::connect. Failed to connect socket to '%s:%d'. Error: '%s' (%d). [%p]",
m_remoteAddr.host().c_str(),m_remoteAddr.port(),
::strerror(m_socket->error()),m_socket->error(),this);
terminate(false,false,0,false);
return;
}
Debug(m_engine,DebugAll,"Stream::connect. Connected to '%s' (Port: %d). [%p]",
Debug(m_engine,DebugAll,"Stream::connect. Connected to '%s:%d'. [%p]",
m_remoteAddr.host().c_str(),m_remoteAddr.port(),this);
// Update restart data
if (m_partialRestart != -1)
@ -152,17 +159,17 @@ void JBComponentStream::terminate(bool destroy, bool sendEnd,
error = 0;
}
cleanup(sendEnd,error);
// Add event
// Add event. Change state
if (destroy) {
Debug(m_engine,DebugAll,"Stream::terminate. Destroy. [%p]",this);
addEvent(JBEvent::Destroy,eventError);
m_state = Destroy;
deref();
return;
}
Debug(m_engine,DebugAll,"Stream::terminate. Terminate. [%p]",this);
addEvent(JBEvent::Terminated,eventError);
m_state = Terminated;
else {
addEvent(JBEvent::Terminated,eventError);
m_state = Destroy;
}
Debug(m_engine,DebugAll,"Stream. %s. [%p]",destroy?"Destroy":"Terminate",this);
}
bool JBComponentStream::receive()
@ -172,25 +179,19 @@ bool JBComponentStream::receive()
m_state == WaitToConnect)
return false;
u_int32_t len = sizeof(buf);
XMLElement* e = 0;
bool sendEnd = false;
// Lock between start read and end consume to serialize input
m_receiveMutex.lock();
if (!readSocket(buf,len))
e = XMPPUtils::createStreamError(XMPPError::HostGone);
bool read = (readSocket(buf,len) && len);
// Parse if received any data and no error
if (!e && len && !m_parser.consume(buf,len)) {
if (read && !m_parser.consume(buf,len)) {
Debug(m_engine,DebugNote,
"Stream::receive. Error parsing data: '%s'. [%p]",
m_parser.ErrorDesc(),this);
XDebug(m_engine,DebugAll,"Parser buffer: %s",buf);
e = XMPPUtils::createStreamError(XMPPError::Xml,m_parser.ErrorDesc());
sendEnd = true;
XMLElement* e = XMPPUtils::createStreamError(XMPPError::Xml,m_parser.ErrorDesc());
terminate(false,true,e,true);
}
m_receiveMutex.unlock();
// Terminate if error occurred
if (e)
terminate(false,sendEnd,e,true);
return len != 0;
}
@ -199,8 +200,8 @@ JBComponentStream::Error JBComponentStream::sendStanza(XMLElement* stanza,
{
if (!stanza)
return ErrorContext;
DDebug(m_engine,DebugAll,"Stream::sendStanza('%s'). Sender id: '%s'. [%p]",
stanza->name(),senderId,this);
DDebug(m_engine,DebugAll,"Stream::sendStanza((%p): '%s'). Sender id: '%s'. [%p]",
stanza,stanza->name(),senderId,this);
XMLElementOut* e = new XMLElementOut(stanza,senderId);
return postXML(e);
}
@ -248,7 +249,7 @@ void JBComponentStream::cancelPending(bool raise, const String* id)
Lock lock(this);
// Cancel elements with id. Raise event if requested
// Don't cancel the first element if partial data was sent:
// The remote's parser will fail
// The remote parser will fail
if (id && *id) {
ListIterator iter(m_outXML);
GenObject* obj;
@ -284,16 +285,18 @@ void JBComponentStream::eventTerminated(const JBEvent* event)
if (event && event == m_lastEvent) {
m_lastEvent = 0;
DDebug(m_engine,DebugAll,
"Stream::eventTerminated. Event: (%p). Type: %u. [%p]",
"Stream::eventTerminated. Event: (%p): %u. [%p]",
event,event->type(),this);
}
}
void JBComponentStream::cleanup(bool endStream, XMLElement* e)
{
Lock2 lock(*this,m_receiveMutex);
if (!m_socket)
if (!m_socket) {
if (e)
delete e;
return;
}
bool partialData = false;
// Remove first element from queue if partial data was sent
ObjList* obj = m_outXML.skipNull();
@ -329,8 +332,8 @@ JBComponentStream::Error JBComponentStream::postXML(XMLElementOut* element)
element->deref();
return ErrorContext;
}
DDebug(m_engine,DebugAll,"Stream::postXML('%s'). [%p]",
element->element()->name(),this);
DDebug(m_engine,DebugAll,"Stream::postXML((%p): '%s'). [%p]",
element->element(),element->element()->name(),this);
// List not empty: the return value will be ErrorPending
// Else: element will be sent
bool pending = (0 != m_outXML.skipNull());
@ -352,12 +355,12 @@ JBComponentStream::Error JBComponentStream::sendXML()
if (m_engine->debugAt(DebugAll)) {
String eStr;
XMPPUtils::print(eStr,e->element());
Debug(m_engine,DebugAll,"Stream::sendXML. [%p]%s",
this,eStr.c_str());
Debug(m_engine,DebugAll,"Stream::sendXML(%p). [%p]%s",
e->element(),this,eStr.c_str());
}
else
Debug(m_engine,DebugAll,"Stream::sendXML('%s'). [%p]",
e->element()->name(),this);
Debug(m_engine,DebugAll,"Stream::sendXML((%p): '%s'). [%p]",
e->element(),e->element()->name(),this);
// Prepare & send
u_int32_t len;
const char* data = e->getData(len);
@ -392,7 +395,7 @@ bool JBComponentStream::sendStreamXML(XMLElement* element, State newState,
this,eStr.c_str());
}
else
Debug(m_engine,DebugAll,"Stream::sendStreamXML(%s). [%p]",
Debug(m_engine,DebugAll,"Stream::sendStreamXML('%s'). [%p]",
element->name(),this);
String tmp, buff;
switch (element->type()) {
@ -451,12 +454,12 @@ bool JBComponentStream::processIncomingXML()
if (m_engine->debugAt(DebugAll)) {
String eStr;
XMPPUtils::print(eStr,element);
Debug(m_engine,DebugAll,"Stream::processIncomingXML [%p]. %s",
this,eStr.c_str());
Debug(m_engine,DebugAll,"Stream::processIncomingXML(%p) [%p]. %s",
element,this,eStr.c_str());
}
else
DDebug(m_engine,DebugCall,"Stream::processIncomingXML('%s'). [%p].",
element->name(),this);
Debug(m_engine,DebugAll,"Stream::processIncomingXML((%p): '%s'). [%p].",
element,element->name(),this);
// Check if we received a stream end or stream error
if (isStreamEnd(element))
break;
@ -480,7 +483,7 @@ bool JBComponentStream::processIncomingXML()
bool JBComponentStream::processStateStarted(XMLElement* e)
{
XDebug(m_engine,DebugAll,"Stream::processStateStarted [%p].",this);
XDebug(m_engine,DebugAll,"Stream::processStateStarted(%p) [%p].",e,this);
// Expect stream start tag
// Check if received element other then 'stream'
if (e->type() != XMLElement::StreamStart)
@ -500,15 +503,14 @@ bool JBComponentStream::processStateStarted(XMLElement* e)
// Get password from engine. Destroy if not accepted
if (!m_engine->acceptOutgoing(m_remoteAddr.host(),m_password)) {
Debug(m_engine,DebugNote,
"Stream::processStateStarted. Not accepted. [%p]",
this);
"Stream::processStateStarted(%p). Not accepted. [%p]",e,this);
terminate(true,true,XMPPUtils::createStreamError(XMPPError::NotAuth),
true);
return true;
}
// Send auth
Debug(m_engine,DebugAll,
"Stream::processStateStarted. Accepted. Send auth. [%p]",this);
"Stream::processStateStarted(%p). Accepted. Send auth. [%p]",e,this);
String handshake;
m_engine->createSHA1(handshake,m_id,m_password);
XMLElement* xml = new XMLElement(XMLElement::Handshake,0,handshake);
@ -520,20 +522,20 @@ bool JBComponentStream::processStateStarted(XMLElement* e)
bool JBComponentStream::processStateAuth(XMLElement* e)
{
XDebug(m_engine,DebugAll,"Stream::processStateAuth. [%p]",this);
XDebug(m_engine,DebugAll,"Stream::processStateAuth(%p). [%p]",e,this);
// Expect handshake
if (e->type() != XMLElement::Handshake)
return unexpectedElement(e);
delete e;
Debug(m_engine,DebugAll,
"Stream::processStateAuth. Authenticated. [%p]",this);
"Stream::processStateAuth(%p). Authenticated. [%p]",e,this);
m_state = Running;
return false;
}
bool JBComponentStream::processStateRunning(XMLElement* e)
{
XDebug(m_engine,DebugAll,"Stream::processStateRunning [%p].",this);
XDebug(m_engine,DebugAll,"Stream::processStateRunning(%p) [%p].",e,this);
switch (e->type()) {
case XMLElement::Iq:
return processIncomingIq(e);
@ -567,7 +569,7 @@ bool JBComponentStream::processIncomingIq(XMLElement* e)
// error: MAY have a first child with the sent stanza
// MUST have an 'error' child
// Check type and the first child's namespace
DDebug(m_engine,DebugAll,"Stream::processIncomingIq. [%p]",this);
DDebug(m_engine,DebugAll,"Stream::processIncomingIq(%p). [%p]",e,this);
XMPPUtils::IqType iq = XMPPUtils::iqType(e->getAttribute("type"));
JBEvent* event = 0;
// Get first child
@ -580,7 +582,7 @@ bool JBComponentStream::processIncomingIq(XMLElement* e)
event = addEvent(JBEvent::IqResult,e);
break;
}
// Child non 0: Fall trough to check the child
// Child non 0: Fall through to check the child
case XMPPUtils::IqSet:
case XMPPUtils::IqGet:
// Jingle ?
@ -592,8 +594,7 @@ bool JBComponentStream::processIncomingIq(XMLElement* e)
}
// Check namespace
if (!child->hasAttribute("xmlns",s_ns[XMPPNamespace::Jingle])) {
sendIqError(e,XMPPError::TypeModify,XMPPError::SNotAcceptable,
"bad-namespace");
sendIqError(e,XMPPError::TypeModify,XMPPError::SFeatureNotImpl);
return false;
}
// Add event
@ -655,13 +656,16 @@ JBEvent* JBComponentStream::addEvent(JBEvent::Type type,
{
Lock2 lock(*this,m_receiveMutex);
JBEvent* ev = new JBEvent(type,this,element,child);
Debug(m_engine,DebugAll,"Stream::addEvent(%p). Type: %u. [%p]",
ev,ev->type(),this);
Debug(m_engine,DebugAll,"Stream::addEvent((%p): %u). [%p]",ev,ev->type(),this);
// Append event
// If we already have a terminated event, ignore the new one
if (type == JBEvent::Destroy || type == JBEvent::Terminated) {
if (m_terminateEvent)
if (m_terminateEvent) {
Debug(m_engine,DebugAll,
"Stream::addEvent. Ignoring terminating event ((%p): %u). Already set. [%p]",
ev,ev->type(),this);
delete ev;
}
else
m_terminateEvent = ev;
return 0;
@ -673,23 +677,22 @@ JBEvent* JBComponentStream::addEvent(JBEvent::Type type,
bool JBComponentStream::addEventNotify(JBEvent::Type type,
XMLElementOut* element)
{
XMLElement* e = 0;
bool raise = (element && element->id());
Lock lock(this);
XMLElement* e = 0;
bool raise = (element->id());
if (raise) {
e = element->release();
JBEvent* ev = new JBEvent(type,this,e,&(element->id()));
Debug(m_engine,DebugAll,
"Stream::addEventNotify(%p). Type: %u. [%p]",
ev,ev->type(),this);
"Stream::addEventNotify((%p): %u). [%p]",ev,ev->type(),this);
m_events.append(ev);
}
else
e = element->element();
// Remove element
DDebug(m_engine,DebugAll,
"Stream::addEventNotify. Remove '%s' from outgoing queue. [%p]",
e ? e->name() : "",this);
"Stream::addEventNotify. Remove (%p): '%s' from outgoing queue. [%p]",
e,e ? e->name() : "",this);
m_outXML.remove(element,true);
return raise;
}
@ -698,8 +701,8 @@ bool JBComponentStream::invalidElement(XMLElement* e, XMPPError::Type type,
const char* text)
{
Debug(m_engine,DebugAll,
"Stream. Received invalid element ('%s') in state %u. Error: '%s'. [%p]",
e->name(),state(),s_err[type],this);
"Stream. Received invalid element ((%p): '%s') in state %u. Error: '%s'. [%p]",
e,e->name(),state(),s_err[type],this);
delete e;
terminate(false,true,XMPPUtils::createStreamError(type,text),true);
return true;
@ -708,8 +711,8 @@ bool JBComponentStream::invalidElement(XMLElement* e, XMPPError::Type type,
bool JBComponentStream::unexpectedElement(XMLElement* e)
{
Debug(m_engine,DebugInfo,
"Stream. Ignoring unexpected element ('%s') in state %u. [%p]",
e->name(),state(),this);
"Stream. Ignoring unexpected element ((%p): '%s') in state %u. [%p]",
e,e->name(),state(),this);
delete e;
return false;
}
@ -731,9 +734,13 @@ bool JBComponentStream::isStreamEnd(XMLElement* e)
bool JBComponentStream::readSocket(char* data, u_int32_t& len)
{
if (state() == Destroy ||
!(m_socket && m_socket->valid()))
if (state() == Destroy)
return false;
// Check socket
if (!(m_socket && m_socket->valid())) {
terminate(false,false,errorHostGone(),false);
return false;
}
// Read socket
int read = m_socket->recv(data,len);
if (read == Socket::socketError()) {
@ -742,6 +749,7 @@ bool JBComponentStream::readSocket(char* data, u_int32_t& len)
Debug(m_engine,DebugWarn,
"Stream::readSocket. Socket error: %d: '%s'. [%p]",
m_socket->error(),::strerror(m_socket->error()),this);
terminate(false,false,errorHostGone(),false);
return false;
}
}
@ -762,7 +770,7 @@ bool JBComponentStream::writeSocket(const char* data, u_int32_t& len)
return false;
// Check socket
if (!(m_socket && m_socket->valid())) {
terminate(false);
terminate(false,false,errorHostGone(),false);
return false;
}
// Write data
@ -774,8 +782,7 @@ bool JBComponentStream::writeSocket(const char* data, u_int32_t& len)
Debug(m_engine,DebugWarn,
"Stream::writeSocket. Socket error: %d: '%s'. [%p]",
m_socket->error(),::strerror(m_socket->error()),this);
XMLElement* e = XMPPUtils::createStreamError(XMPPError::HostGone);
terminate(false,false,e,false);
terminate(false,false,errorHostGone(),false);
return false;
}
DDebug(m_engine,DebugMild,

View File

@ -51,7 +51,7 @@ void JGEngine::initialize(const NamedList& params)
JGSession* JGEngine::call(const String& localJID, const String& remoteJID,
XMLElement* media, XMLElement* transport, const char* message)
{
DDebug(this,DebugAll,"call. New outgoing call from '%s' to '%s'",
DDebug(this,DebugAll,"call. New outgoing call from '%s' to '%s'.",
localJID.c_str(),remoteJID.c_str());
JBComponentStream* stream = m_engine->getStream();
if (stream) {
@ -66,7 +66,7 @@ JGSession* JGEngine::call(const String& localJID, const String& remoteJID,
}
session->deref();
}
DDebug(this,DebugAll,"call. Outgoing call to '%s' failed",remoteJID.c_str());
DDebug(this,DebugCall,"call. Outgoing call to '%s' failed. No stream.",remoteJID.c_str());
return 0;
}
@ -113,7 +113,7 @@ bool JGEngine::process()
break;
ok = true;
if (event->type() == JGEvent::Destroy) {
DDebug(this,DebugAll,"Deleting internal event 'Destroy'.");
DDebug(this,DebugAll,"Deleting internal event(%p) 'Destroy'.",event);
delete event;
continue;
}
@ -157,8 +157,8 @@ void JGEngine::defProcessEvent(JGEvent* event)
{
if (!event)
return;
DDebug(this,DebugAll,"JGEngine::defprocessEvent. Type %u. Delete event.",
event->type());
DDebug(this,DebugAll,"JGEngine::defprocessEvent. Deleting event(%p). Type %u.",
event,event->type());
delete event;
}

View File

@ -147,10 +147,9 @@ JGSession::JGSession(JGEngine* engine, JBComponentStream* stream,
m_engine->createSessionId(m_localSid);
m_sid = m_localSid;
m_localJID.set(callerJID);
m_initiatorJID.set(m_localJID);
m_remoteJID.set(calledJID);
DDebug(m_engine,DebugAll,"Session [%p]. Outgoing. ID: '%s'",
this,m_sid.c_str());
DDebug(m_engine,DebugAll,"Session. Outgoing. ID: '%s'. [%p]",
m_sid.c_str(),this);
}
JGSession::JGSession(JGEngine* engine, JBEvent* event)
@ -167,7 +166,7 @@ JGSession::JGSession(JGEngine* engine, JBEvent* event)
// This should never happen
if (!(event && event->stream() && event->stream()->ref() &&
event->element() && event->child())) {
Debug(m_engine,DebugFail,"Session [%p]. Incoming. Invalid event.",this);
Debug(m_engine,DebugFail,"Session. Incoming. Invalid event. [%p]",this);
if (event)
event->deref();
m_state = Destroy;
@ -181,8 +180,8 @@ JGSession::JGSession(JGEngine* engine, JBEvent* event)
event->child()->getAttribute("id",m_sid);
// Create local sid
m_engine->createSessionId(m_localSid);
DDebug(m_engine,DebugAll,"Session [%p]. Incoming. ID: '%s'",
this,m_sid.c_str());
DDebug(m_engine,DebugAll,"Session. Incoming. ID: '%s'. [%p]",
m_sid.c_str(),this);
}
JGSession::~JGSession()
@ -195,25 +194,27 @@ JGSession::~JGSession()
}
m_events.clear();
m_engine->removeSession(this);
DDebug(m_engine,DebugAll,"~Session [%p].",this);
DDebug(m_engine,DebugAll,"~Session. [%p]",this);
}
bool JGSession::sendMessage(const char* message)
{
XMLElement* xml = XMPPUtils::createMessage(XMPPUtils::MsgChat,
m_localJID,m_remoteJID,"",message);
return sendXML(xml);
m_localJID,m_remoteJID,0,message);
return sendXML(xml,false);
}
bool JGSession::hangup(bool reject, const char* message)
{
if (!(state() == Pending || state() == Active))
return false;
DDebug(m_engine,DebugAll,"Session::Hangup [%p]. Message: '%s'.",this,message);
if (message && !sendMessage(message))
return false;
XMLElement* xml = createJingleSet(reject ? ActReject : ActTerminate);
Lock lock(this);
DDebug(m_engine,DebugAll,"Session. %s('%s'). [%p]",
reject?"Reject":"Hangup",message,this);
if (message)
sendMessage(message);
XMLElement* xml = createJingleSet(reject ? ActReject : ActTerminate);
// Clear sent stanzas list. We will wait for this element to be confirmed
m_sentStanza.clear();
m_state = Ending;
m_timeout = Time::msecNow() + JGSESSION_ENDTIMEOUT * 1000;
@ -274,8 +275,8 @@ bool JGSession::receive(JBEvent* event)
return false;
// Check destination
DDebug(m_engine,DebugAll,
"Session::receive [%p]. Check event (%p) from Jabber. Type: %u. To: '%s'",
this,event,event->type(),event->to().c_str());
"Session. Check event ((%p): %u) from Jabber. [%p]",
event,event->type(),this);
switch (event->type()) {
// Incoming data is accepted if 'to' is this session
case JBEvent::IqResult:
@ -294,10 +295,12 @@ bool JGSession::receive(JBEvent* event)
case JBEvent::Destroy:
lock();
// Ignore: session is already ending or destroying
if (state() == Ending && state() != Destroy) {
if (state() != Ending && state() != Destroy) {
DDebug(m_engine,DebugAll,
"Session. Terminate on stream destroy. [%p]",this);
m_state = Destroy;
m_lastEvent = new JGEvent(JGEvent::Terminated,this);
m_lastEvent->m_reason = "Stream terminated";
m_lastEvent->m_reason = "noconn";
}
unlock();
return false;
@ -308,14 +311,14 @@ bool JGSession::receive(JBEvent* event)
// Delete event if in terminating state
if (state() == Destroy) {
DDebug(m_engine,DebugAll,
"Session::receive [%p]. Received event (%p. Type: %u) from Jabber in terminating state. Deleting.",
this,event,event->type());
"Session. Received event ((%p). %u) from Jabber in terminating state. Deleting. [%p]",
event,event->type(),this);
event->deref();
return true;
}
DDebug(m_engine,DebugAll,
"Session::receive [%p]. Accepted event (%p) from Jabber. Type: %u.",
this,event,event->type());
"Session. Accepted event ((%p): %u) from Jabber. [%p]",
event,event->type(),this);
// Unlock stream events
event->releaseStream();
// Keep event
@ -338,8 +341,8 @@ JGEvent* JGSession::getEvent(u_int64_t time)
// Process the event
JBEvent* jbev = static_cast<JBEvent*>(obj);
DDebug(m_engine,DebugAll,
"Session::getEvent [%p]. Process received element with id '%s'",
this,jbev->id().c_str());
"Session. Process Jabber event ((%p): %u). [%p]",
jbev,jbev->type(),this);
JGEvent* event = processEvent(jbev,time);
// No event: check timeout
if (!event && timeout(time)) {
@ -348,8 +351,8 @@ JGEvent* JGSession::getEvent(u_int64_t time)
}
// Remove jabber event
DDebug(m_engine,DebugAll,
"Session::getEvent [%p]. Remove Jabber event (%p) from queue",
this,jbev);
"Session. Remove Jabber event ((%p): %u) from queue. [%p]",
jbev,jbev->type(),this);
m_events.remove(jbev,true);
// Raise ?
if (event)
@ -364,7 +367,7 @@ JGEvent* JGSession::getEvent(u_int64_t time)
JGEvent* JGSession::badRequest(JGEvent* event)
{
DDebug(m_engine,DebugAll,"Session::badRequest [%p].",this);
XDebug(m_engine,DebugAll,"Session::badRequest. [%p]",this);
sendEBadRequest(event->releaseXML());
delete event;
return 0;
@ -377,8 +380,8 @@ JGEvent* JGSession::processEvent(JBEvent* jbev, u_int64_t time)
if (state() == Ending) {
if (isResponse(jbev) || time > m_timeout) {
DDebug(m_engine,DebugAll,
"Session [%p]. Terminated in state Ending. Reason: '%s'.",
this,time > m_timeout ? "Timeout" : "Hangup");
"Session. Terminated in state Ending. Reason: '%s'. [%p]",
this,time > m_timeout ? "timeout" : "hangup");
event = new JGEvent(JGEvent::Destroy,this);
}
}
@ -405,7 +408,7 @@ JGEvent* JGSession::processEvent(JBEvent* jbev, u_int64_t time)
JGEvent* JGSession::processStatePending(JBEvent* jbev, JGEvent* event)
{
DDebug(m_engine,DebugAll,"Session::processStatePending [%p].",this);
XDebug(m_engine,DebugAll,"Session::processStatePending. [%p]",this);
// Check event type
if (event->type() != JGEvent::Jingle) {
confirmIq(event->element());
@ -432,7 +435,7 @@ JGEvent* JGSession::processStatePending(JBEvent* jbev, JGEvent* event)
JGEvent* JGSession::processStateActive(JBEvent* jbev, JGEvent* event)
{
DDebug(m_engine,DebugAll,"Session::processStateActive [%p].",this);
XDebug(m_engine,DebugAll,"Session::processStateActive. [%p]",this);
if (event->type() == JGEvent::Terminated)
m_state = Destroy;
confirmIq(event->element());
@ -441,7 +444,7 @@ JGEvent* JGSession::processStateActive(JBEvent* jbev, JGEvent* event)
JGEvent* JGSession::processStateIdle(JBEvent* jbev, JGEvent* event)
{
DDebug(m_engine,DebugAll,"Session::processStateIdle [%p].",this);
XDebug(m_engine,DebugAll,"Session::processStateIdle. [%p]",this);
if (!incoming())
return badRequest(event);
if (event->action() != ActInitiate) {
@ -451,8 +454,6 @@ JGEvent* JGSession::processStateIdle(JBEvent* jbev, JGEvent* event)
m_localJID.set(jbev->to());
m_remoteJID.set(jbev->from());
confirmIq(event->element());
if (jbev->child())
m_initiatorJID.set(jbev->child()->getAttribute("initiator"));
m_state = Pending;
return event;
}
@ -504,7 +505,7 @@ bool JGSession::decodeJingle(JGEvent* event)
sendEServiceUnavailable(event->releaseXML());
return false;
}
// Get payloads
// Get transports
XMLElement* t = trans->findFirstChild(XMLElement::Candidate);
for (; t; t = trans->findNextChild(t,XMLElement::Candidate)) {
JGTransport* tr = new JGTransport(t);
@ -545,8 +546,8 @@ JGEvent* JGSession::createEvent(JBEvent* jbev)
switch (jbev->type()) {
case JBEvent::IqResult:
DDebug(m_engine,DebugAll,
"Session::createEvent [%p]. Received confirmation. ID: '%s'.",
this,jbev->id().c_str());
"Session. Received confirmation. ID: '%s'. [%p]",
jbev->id().c_str(),this);
sent = isResponse(jbev);
if (sent)
m_sentStanza.remove(sent,true);
@ -558,8 +559,8 @@ JGEvent* JGSession::createEvent(JBEvent* jbev)
break;
case JBEvent::IqError:
DDebug(m_engine,DebugAll,
"Session::createEvent [%p]. Received error. ID: '%s'.",
this,jbev->id().c_str());
"Session. Received error. ID: '%s'. [%p]",
jbev->id().c_str(),this);
sent = isResponse(jbev);
if (sent)
m_sentStanza.remove(sent,true);
@ -570,7 +571,7 @@ JGEvent* JGSession::createEvent(JBEvent* jbev)
sent = isResponse(jbev);
if (sent)
m_sentStanza.remove(sent,true);
event->m_reason = "socket-error";
event->m_reason = "noconn";
event->m_type = JGEvent::Terminated;
return event;
default: ;
@ -582,8 +583,8 @@ JGEvent* JGSession::createEvent(JBEvent* jbev)
JGEvent* JGSession::raiseEvent(JGEvent* event)
{
if (m_lastEvent)
Debug(m_engine,DebugGoOn,"Session::raiseEvent [%p]. Last event already set to %p.",
this,m_lastEvent);
Debug(m_engine,DebugGoOn,"Session::raiseEvent. Last event already set to %p. [%p]",
m_lastEvent,this);
m_lastEvent = event;
// Do specific actions: change state, deref() ...
switch (event->type()) {
@ -596,8 +597,8 @@ JGEvent* JGSession::raiseEvent(JGEvent* event)
break;
default: ;
}
DDebug(m_engine,DebugAll,"Session::raiseEvent [%p]. Event (%p) type: %u. Action: %u.",
this,event,event->type(),event->action());
DDebug(m_engine,DebugAll,"Session. Raising event((%p): %u). Action: %u. [%p]",
event,event->type(),event->action(),this);
return event;
}
@ -605,7 +606,7 @@ bool JGSession::initiate(XMLElement* media, XMLElement* transport)
{
if (incoming() || state() != Idle)
return false;
DDebug(m_engine,DebugAll,"Session::initiate [%p]. From: '%s' To: '%s'",
DDebug(m_engine,DebugAll,"Session. Initiate from '%s' to '%s'. [%p]",
this,m_localJID.c_str(),m_remoteJID.c_str());
XMLElement* xml = createJingleSet(ActInitiate,media,transport);
if (sendXML(xml))
@ -617,7 +618,8 @@ bool JGSession::sendXML(XMLElement* e, bool addId)
{
if (!e)
return false;
DDebug(m_engine,DebugAll,"Session::sendXML ('%s') [%p].",e->name(),this);
Lock lock(this);
DDebug(m_engine,DebugAll,"Session::sendXML((%p): '%s'). [%p]",e,e->name(),this);
if (addId) {
// Create id
String id = m_localSid;
@ -645,9 +647,8 @@ XMLElement* JGSession::createJingleSet(Action action,
XMPPNamespace::Jingle);
if (action < ActCount)
jingle->setAttribute("type",actionText(action));
jingle->setAttribute("initiator",m_initiatorJID);
// if (incoming())
// jingle->setAttribute("responder",m_localJID);
jingle->setAttribute("initiator",initiator());
// jingle->setAttribute("responder",incoming()?m_localJID:m_remoteJID);
jingle->setAttribute("id",m_sid);
if (media)
jingle->addChild(media);
@ -661,12 +662,10 @@ void JGSession::confirmIq(XMLElement* element)
{
if (!(element && element->type() == XMLElement::Iq))
return;
XMPPUtils::IqType type = XMPPUtils::iqType(element->getAttribute("type"));
if (type == XMPPUtils::IqResult || type == XMPPUtils::IqError)
return;
String id = element->getAttribute("id");
sendResult(id);
}
@ -675,11 +674,12 @@ void JGSession::eventTerminated(JGEvent* event)
lock();
if (event == m_lastEvent) {
DDebug(m_engine,DebugAll,
"Session::eventTerminated [%p]. Event (%p).",this,event);
"Session. Event((%p): %u) terminated. [%p]",event,event->type(),this);
m_lastEvent = 0;
}
else if (m_lastEvent)
Debug(m_engine,DebugNote,"Event %p replaced while processed [%p]",event,this);
Debug(m_engine,DebugNote,"Event((%p): %u) replaced while processed. [%p]",
event,event->type(),this);
unlock();
}
@ -691,8 +691,8 @@ JGSentStanza* JGSession::isResponse(const JBEvent* jbev)
JGSentStanza* tmp = static_cast<JGSentStanza*>(obj->get());
if (tmp->isResponse(jbev)) {
DDebug(m_engine,DebugAll,
"Session [%p]. Sent element with id '%s' confirmed.",
this,tmp->m_id.c_str());
"Session. Sent element with id '%s' confirmed. [%p]",
tmp->m_id.c_str(),this);
return tmp;
}
}
@ -707,8 +707,8 @@ bool JGSession::timeout(u_int64_t time)
JGSentStanza* tmp = static_cast<JGSentStanza*>(obj->get());
if (tmp->timeout(time)) {
DDebug(m_engine,DebugAll,
"Session [%p]. Sent element with id '%s' timed out.",
this,tmp->m_id.c_str());
"Session. Sent element with id '%s' timed out. [%p]",
tmp->m_id.c_str(),this);
return true;
}
}

View File

@ -55,7 +55,7 @@ XMLElement::XMLElement()
: m_type(StreamEnd), m_owner(true), m_element(0)
{
m_element = new TiXmlElement(typeName(m_type));
// DDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
// XDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
}
XMLElement::XMLElement(const char* name, NamedList* attributes,
@ -77,7 +77,7 @@ XMLElement::XMLElement(const char* name, NamedList* attributes,
}
}
setType();
// DDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name);
// XDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name);
}
XMLElement::XMLElement(Type type, NamedList* attributes,
@ -98,21 +98,21 @@ XMLElement::XMLElement(Type type, NamedList* attributes,
m_element->SetAttribute(ns->name().c_str(),ns->c_str());
}
}
// DDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
// XDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
}
XMLElement::XMLElement(TiXmlElement* element, bool owner)
: m_type(Unknown), m_owner(owner), m_element(element)
{
setType();
// DDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
// XDDebug(DebugAll,"XMLElement::XMLElement [%p]. Name: '%s'",this,name());
}
XMLElement::~XMLElement()
{
if (m_owner && m_element)
delete m_element;
// DDebug(DebugAll,"XMLElement::~XMLElement [%p]. Name: '%s'",this,name());
// XDebug(DebugAll,"XMLElement::~XMLElement [%p]. Name: '%s'",this,name());
}
void XMLElement::toString(String& dest, bool unclose) const

View File

@ -358,7 +358,8 @@ XMLElement* XMPPUtils::createMessage(MsgType type, const char* from,
msg->setAttribute("type",lookup(type,s_msg,""));
msg->setAttribute("from",from);
msg->setAttribute("to",to);
msg->setAttribute("id",id);
if (id)
msg->setAttributeValid("id",id);
msg->addChild(new XMLElement(XMLElement::Body,0,message));
return msg;
}

View File

@ -661,9 +661,9 @@ public:
* Print an XMLElement to a string.
* @param xmlStr The destination string.
* @param element The element to print.
* @param indent The indent.
* @param indent The indent. 0 if it is the root element.
*/
static void print(String& xmlStr, XMLElement* element, const char* indent = "");
static void print(String& xmlStr, XMLElement* element, const char* indent = 0);
/**
* Get the type of an 'iq' stanza as enumeration.

View File

@ -995,18 +995,19 @@ public:
* @param text The text to check.
* @return Presence type as enumeration.
*/
static Presence presenceType(const char* txt);
static inline Presence presenceType(const char* txt)
{ return (Presence)lookup(txt,s_presence,None); }
/**
* Get the text from a presence type.
* @param presence The presence type.
* @return The associated text or 0.
*/
static const char* presenceText(Presence presence);
static inline const char* presenceText(Presence presence)
{ return lookup(presence,s_presence,0); }
protected:
ObjList m_events; // Incoming events from Jabber engine
static const char* s_presence[]; // Keep the types of 'presence'
static TokenDict s_presence[]; // Keep the types of 'presence'
};
};

View File

@ -40,8 +40,8 @@ class JGEngine;
class JGSentStanza;
// Defines
#define JGSESSION_ENDTIMEOUT 2 // Time to wait before destroing a session after hangup
#define JGSESSION_STANZATIMEOUT 10 // Time to wait for a response
#define JGSESSION_ENDTIMEOUT 2 // Time to wait before destroing a session after hangup
#define JGSESSION_STANZATIMEOUT 10 // Time to wait for a response
/**
* This class holds a Jingle audio payload description.
@ -576,7 +576,6 @@ private:
String m_sid; // Session id
JabberID m_localJID; // Local peer's JID
JabberID m_remoteJID; // Remote peer's JID
JabberID m_initiatorJID; // Initiator's JID
// Session data
ObjList m_events; // Incoming events from Jabber engine
JGEvent* m_lastEvent; // Last generated event
@ -740,7 +739,7 @@ public:
/**
* Initialize this engine.
* Parameters:
* Parameters: None
* @param params Engine's parameters.
*/
void initialize(const NamedList& params);

View File

@ -69,11 +69,11 @@ static TokenDict dict_payloads[] = {
{ 0, 0 },
};
#define JINGLE_RESOURCE "Talk" // Default resource for local party
#define JINGLE_VOICE "voice-v1" // Voice capability for Google Talk
#define JINGLE_VERSION "1.0" // Version capability
#define JINGLE_RESOURCE "Talk" // Default resource for local party
#define JINGLE_VOICE "voice-v1" // Voice capability for Google Talk
#define JINGLE_VERSION "1.0" // Version capability
#define JINGLE_AUTHSTRINGLEN 16 // Username/Password length for transport
#define JINGLE_AUTHSTRINGLEN 16 // Username/Password length for transport
/**
* YJBEngine
@ -148,10 +148,12 @@ private:
class YJGEngine : public JGEngine
{
public:
inline YJGEngine(YJBEngine* jb, const NamedList& jgParams, bool requestSubscribe)
: JGEngine(jb,jgParams), m_requestSubscribe(requestSubscribe) {}
inline YJGEngine(YJBEngine* jb, const NamedList& jgParams)
: JGEngine(jb,jgParams), m_requestSubscribe(true) {}
virtual ~YJGEngine() {}
virtual void processEvent(JGEvent* event);
void requestSubscribe(bool value)
{ m_requestSubscribe = value; }
bool requestSubscribe()
{ return m_requestSubscribe; }
// Start thread members
@ -255,8 +257,6 @@ public:
bool updateTransport(ObjList& transport, bool start = false);
// Start RTP
bool start();
// chan.stun
void startStun();
// Send transport through the given session
inline bool send(JGSession* session)
{ return session->requestTransport(new JGTransport(*this)); }
@ -267,12 +267,12 @@ public:
protected:
bool m_mediaReady; // Media ready (updated) flag
bool m_transportReady; // Transport ready (both parties) flag
bool m_started; // True if chan.stun already sent
JGTransport* m_remote; // The remote transport info
ObjList m_formats; // The media formats
YJGConnection* m_connection; // The connection
RefObject* m_rtpData;
String m_rtpId;
// String m_socketFilter; // The socket for the STUN filter
};
/**
@ -297,10 +297,9 @@ public:
{ return m_local; }
inline const JabberID& remote() const
{ return m_remote; }
virtual void YJGConnection::callAccept(Message& msg);
virtual void YJGConnection::callRejected(const char* error,
const char* reason, const Message* msg);
virtual bool YJGConnection::callRouted(Message& msg);
virtual void callAccept(Message& msg);
virtual void callRejected(const char* error, const char* reason, const Message* msg);
virtual bool callRouted(Message& msg);
virtual void disconnected(bool final, const char* reason);
virtual bool msgAnswered(Message& msg);
virtual bool msgUpdate(Message& msg);
@ -339,7 +338,7 @@ private:
};
/**
* LibThread
* YJGLibThread
* Thread class for library asynchronous operations
*/
class YJGLibThread : public Thread
@ -353,17 +352,10 @@ public:
JGProcess, // m_jg->runProcess()
JBPresence, // m_presence->runProcess()
};
inline YJGLibThread(Action action, const char* name = 0,
Priority prio = Normal)
: Thread(name,prio), m_action(action), m_stream(0)
{}
inline YJGLibThread(JBComponentStream* stream, const char* name = 0,
Priority prio = Normal)
: Thread(name,prio), m_action(JBConnect), m_stream(0)
{
if (stream && stream->ref())
m_stream = stream;
}
YJGLibThread(Action action, const char* name = 0,
Priority prio = Normal);
YJGLibThread(JBComponentStream* stream, const char* name = 0,
Priority prio = Normal);
virtual void run();
protected:
Action m_action; // Action
@ -534,7 +526,7 @@ void YJBPresence::processProbe(JBEvent* event)
if (local.bare() != yup->local().bare() || remote != yup->remote())
continue;
found = true;
XDebug(this,DebugAll,"processProbe. Sending probe from existing %p.",yup);
XDebug(this,DebugAll,"processProbe. Sending presence from existing %p.",yup);
yup->send();
}
if (found)
@ -1167,6 +1159,7 @@ YJGTransport::YJGTransport(YJGConnection* connection, Message* msg)
: Mutex(true),
m_mediaReady(false),
m_transportReady(false),
m_started(false),
m_remote(0),
m_connection(connection),
m_rtpData(0)
@ -1243,8 +1236,11 @@ bool YJGTransport::initLocal()
m_connection->getRemoteAddr(s);
m.setParam("remoteip",s);
}
if (!Engine::dispatch(m))
if (!Engine::dispatch(m)) {
DDebug(m_connection,DebugAll,"Transport. Init RTP failed. [%p]",
m_connection);
return false;
}
m_address = m.getValue("localip",m_address);
m_port = m.getValue("localport","-1");
return true;
@ -1253,11 +1249,11 @@ bool YJGTransport::initLocal()
bool YJGTransport::start()
{
Lock lock(this);
if (!(m_connection && m_mediaReady && m_transportReady))
if (m_started || !(m_connection && m_mediaReady && m_transportReady))
return false;
DDebug(m_connection,DebugCall,"Transport. Start. Local: '%s:%s'. Remote: '%s:%s'.",
DDebug(m_connection,DebugCall,"Transport. Start. Local: '%s:%s'. Remote: '%s:%s'. [%p]",
m_address.c_str(),m_port.c_str(),
m_remote->m_address.c_str(),m_remote->m_port.c_str());
m_remote->m_address.c_str(),m_remote->m_port.c_str(),m_connection);
Message* m = new Message("chan.rtp");
m->userData(static_cast<CallEndpoint*>(m_connection));
m_connection->complete(*m);
@ -1273,7 +1269,9 @@ bool YJGTransport::start()
m->addParam("rtcp","false");
m->addParam("getsession","true");
if (!Engine::dispatch(m)) {
DDebug(m_connection,DebugAll,"Transport. 'chan.rtp' failed.");
Debug(m_connection,DebugCall,"Transport. Start RTP failed. [%p]",
m_connection);
delete m;
return false;
}
// chan.stun
@ -1286,27 +1284,14 @@ bool YJGTransport::start()
msg->addParam("userid",m->getValue("rtpid"));
delete m;
Engine::enqueue(msg);
m_started = true;
return true;
}
void YJGTransport::startStun()
{
if (!m_transportReady)
return;
Message* msg = new Message("chan.stun");
msg->userData(m_rtpData);
msg->addParam("userid",m_rtpId);
// msg->addParam("socketfilter",m_socketFilter);
msg->addParam("localusername",m_remote->m_username + m_username);
msg->addParam("remoteusername",m_username + m_remote->m_username);
msg->addParam("remoteip",m_remote->m_address);
msg->addParam("remoteport",m_remote->m_port);
msg->addParam("userid",m_connection->id());
Engine::enqueue(msg);
}
bool YJGTransport::updateMedia(ObjList& media, bool start)
{
if (!m_connection)
return false;
Lock lock(this);
if (m_mediaReady) {
if (start)
@ -1315,8 +1300,10 @@ bool YJGTransport::updateMedia(ObjList& media, bool start)
}
// Check if we received any media
if (0 == media.skipNull()) {
DDebug(m_connection,DebugWarn,"Transport. The remote party has no media. Reject.");
m_connection->hangup(true,"nomedia");
DDebug(m_connection,DebugWarn,
"Transport. The remote party has no media. [%p]",
m_connection);
m_connection->hangup(false,"nomedia");
return false;
}
ListIterator iter_local(m_formats);
@ -1342,12 +1329,13 @@ bool YJGTransport::updateMedia(ObjList& media, bool start)
// Check if both parties have common media
if (0 == m_formats.skipNull()) {
DDebug(m_connection,DebugWarn,
"Transport. Unable to negotiate media (no common formats). Reject.");
m_connection->hangup(true,"nomedia");
"Transport. Unable to negotiate media (no common formats). [%p]",
m_connection);
m_connection->hangup(false,"nomedia");
return false;
}
m_mediaReady = true;
DDebug(m_connection,DebugCall,"Transport. Media is ready.");
DDebug(m_connection,DebugCall,"Transport. Media is ready. [%p]",m_connection);
if (start)
return this->start();
return true;
@ -1384,9 +1372,9 @@ bool YJGTransport::updateTransport(ObjList& transport, bool start)
m_remote = new JGTransport(*remote);
m_transportReady = true;
DDebug(m_connection,DebugCall,
"Transport. Transport is ready. Local: '%s:%s'. Remote: '%s:%s'.",
"Transport. Transport is ready. Local: '%s:%s'. Remote: '%s:%s'. [%p]",
m_address.c_str(),m_port.c_str(),
m_remote->m_address.c_str(),m_remote->m_port.c_str());
m_remote->m_address.c_str(),m_remote->m_port.c_str(),m_connection);
if (start)
return this->start();
return true;
@ -1441,7 +1429,7 @@ YJGConnection::YJGConnection(YJGEngine* jgEngine, Message* msg, const char* call
m_transport(0),
m_hangup(false)
{
XDebug(this,DebugInfo,"YJGConnection [%p]. Outgoing.",this);
XDebug(this,DebugInfo,"YJGConnection. Outgoing. [%p]",this);
if (msg)
m_callerPrompt = msg->getValue("callerprompt");
// Init transport
@ -1474,7 +1462,7 @@ YJGConnection::YJGConnection(YJGEngine* jgEngine, JGEvent* event)
m_transport(0),
m_hangup(false)
{
XDebug(this,DebugInfo,"YJGConnection [%p]. Incoming.",this);
XDebug(this,DebugInfo,"YJGConnection. Incoming. [%p]",this);
// Set session
m_session->jingleConn(this);
// Init transport
@ -1520,7 +1508,7 @@ void YJGConnection::callAccept(Message& msg)
// Accept session and transport
// Request transport
// Try to start transport
DDebug(this,DebugCall,"callAccept [%p].",this);
DDebug(this,DebugCall,"callAccept. [%p]",this);
m_transport->initLocal();
m_session->accept(m_transport->createDescription());
m_session->acceptTransport(0);
@ -1537,32 +1525,31 @@ void YJGConnection::callRejected(const char* error, const char* reason,
m_reason = error;
else
m_reason = reason;
DDebug(this,DebugCall,"callRejected [%p]. Reason: '%s'.",
this,m_reason.c_str());
DDebug(this,DebugCall,"callRejected. Reason: '%s'. [%p]",m_reason.c_str(),this);
hangup(true);
}
bool YJGConnection::callRouted(Message& msg)
{
DDebug(this,DebugCall,"callRouted [%p].",this);
DDebug(this,DebugCall,"callRouted. [%p]",this);
return true;
}
void YJGConnection::disconnected(bool final, const char* reason)
{
DDebug(this,DebugCall,"disconnected [%p].",this);
DDebug(this,DebugCall,"disconnected. [%p]",this);
Channel::disconnected(final,reason?reason:m_reason.c_str());
}
bool YJGConnection::msgAnswered(Message& msg)
{
DDebug(this,DebugCall,"msgAnswered [%p].",this);
DDebug(this,DebugCall,"msgAnswered. [%p]",this);
return true;
}
bool YJGConnection::msgUpdate(Message& msg)
{
DDebug(this,DebugCall,"msgUpdate [%p].",this);
DDebug(this,DebugCall,"msgUpdate. [%p]",this);
return true;
}
@ -1586,7 +1573,7 @@ void YJGConnection::hangup(bool reject, const char* reason)
m_session->jingleConn(0);
m_session->hangup(reject,m_reason);
}
DDebug(this,DebugCall,"hangup [%p]. Reason: '%s'",this,m_reason.c_str());
Debug(this,DebugCall,"hangup. Reason: '%s'. [%p]",m_reason.c_str(),this);
}
void YJGConnection::handleEvent(JGEvent* event)
@ -1599,16 +1586,17 @@ void YJGConnection::handleEvent(JGEvent* event)
break;
case JGEvent::Terminated:
m_reason = event->reason();
DDebug(this,DebugCall,"handleEvent [%p]. Terminated. Reason: '%s'.",
this,m_reason.c_str());
DDebug(this,DebugCall,"handleEvent((%p): %u). Terminated. Reason: '%s'. [%p]",
event,event->type(),m_reason.c_str(),this);
break;
case JGEvent::Error:
DDebug(this,DebugCall,
"handleEvent [%p]. Error. Id: '%s'. Reason: '%s'. Text: '%s'.",
this,event->id().c_str(),event->reason().c_str(),event->text().c_str());
"handleEvent((%p): %u). Error. Id: '%s'. Reason: '%s'. Text: '%s'. [%p]",
event,event->type(),event->id().c_str(),event->reason().c_str(),
event->text().c_str(),this);
break;
default:
DDebug(this,DebugCall,"handleEvent [%p]. Event (%p) type: %u.",
DDebug(this,DebugCall,"handleEvent((%p): %u). [%p]",
this,event,event->type());
}
}
@ -1620,21 +1608,21 @@ void YJGConnection::handleJingle(JGEvent* event)
{
bool accept = !m_transport->transportReady() &&
m_transport->updateTransport(event->transport());
DDebug(this,DebugInfo,"handleJingle [%p]. Transport-info. %s.",
this,accept?"Accepted":"Not accepted");
DDebug(this,DebugInfo,"handleJingle. Transport-info. %s. [%p]",
accept?"Accepted":"Not accepted",this);
if (accept && isOutgoing())
m_session->acceptTransport(0);
}
m_transport->start();
break;
case JGSession::ActTransportAccept:
DDebug(this,DebugNote,"handleJingle [%p]. Transport-accept.",this);
DDebug(this,DebugNote,"handleJingle. Transport-accept. [%p]",this);
break;
case JGSession::ActAccept:
if (isAnswered())
break;
// Update media
Debug(this,DebugCall,"handleJingle [%p]. Accept.",this);
Debug(this,DebugCall,"handleJingle. Accepted. [%p]",this);
m_transport->updateMedia(event->audio(),true);
// Notify engine
maxcall(0);
@ -1642,30 +1630,30 @@ void YJGConnection::handleJingle(JGEvent* event)
Engine::enqueue(message("call.answered",false,true));
break;
case JGSession::ActModify:
Debug(this,DebugWarn,"handleJingle [%p]. Modify: not implemented.",this);
Debug(this,DebugWarn,"handleJingle. Modify: not implemented. [%p]",this);
break;
case JGSession::ActRedirect:
Debug(this,DebugWarn,"handleJingle [%p]. Redirect: not implemented. Hangup.",this);
Debug(this,DebugWarn,"handleJingle. Redirect: not implemented. [%p]",this);
break;
default: ;
DDebug(this,DebugWarn,
"handleJingle [%p]. Event (%p). Action: %u. Unexpected.",
this,event,event->action());
"handleJingle. Event (%p). Action: %u. Unexpected. [%p]",
event,event->action(),this);
}
}
bool YJGConnection::processPresence(bool available, const char* error)
{
if (m_state == Terminated) {
DDebug(this,DebugCall,
"processPresence [%p]. Received presence in Terminated state.",this);
DDebug(this,DebugInfo,
"processPresence. Received presence in Terminated state. [%p]",this);
return false;
}
// Check if error or unavailable in any other state
if (!(error || available))
error = "offline";
if (error) {
DDebug(this,DebugCall,"processPresence [%p]. Hangup (%s).",this,error);
DDebug(this,DebugCall,"processPresence. Hangup (%s). [%p]",error,this);
hangup(false,error);
return true;
}
@ -1674,8 +1662,8 @@ bool YJGConnection::processPresence(bool available, const char* error)
return false;
// Make the call
m_state = Active;
DDebug(this,DebugCall,"call [%p]. Caller: '%s'. Called: '%s'.",
this,m_local.c_str(),m_remote.c_str());
Debug(this,DebugCall,"call. Caller: '%s'. Called: '%s'. [%p]",
m_local.c_str(),m_remote.c_str(),this);
// Make the call
m_session = iplugin.m_jg->call(m_local,m_remote,
m_transport->createDescription(),
@ -1696,6 +1684,19 @@ bool YJGConnection::processPresence(bool available, const char* error)
/**
* YJGLibThread
*/
YJGLibThread::YJGLibThread(Action action, const char* name, Priority prio)
: Thread(name,prio), m_action(action), m_stream(0)
{
}
YJGLibThread::YJGLibThread(JBComponentStream* stream, const char* name,
Priority prio)
: Thread(name,prio), m_action(JBConnect), m_stream(0)
{
if (stream && stream->ref())
m_stream = stream;
}
void YJGLibThread::run()
{
switch (m_action) {
@ -1922,14 +1923,14 @@ void YJGDriver::initJG(const NamedList& sect)
if (m_jg)
m_jg->initialize(sect);
else {
bool req = sect.getBoolValue("request_subscribe",true);
m_jg = new YJGEngine(m_jb,sect,req);
m_jg = new YJGEngine(m_jb,sect);
m_jg->debugChain(this);
// Init threads
int read = 1;
int process = 1;
m_jg->startThreads(read,process);
}
m_jg->requestSubscribe(sect.getBoolValue("request_subscribe",true));
}
bool YJGDriver::msgExecute(Message& msg, String& dest)
@ -1949,6 +1950,8 @@ bool YJGDriver::msgExecute(Message& msg, String& dest)
}
JabberID caller(msg.getValue("caller"),identity,JINGLE_RESOURCE);
JabberID called(dest);
DDebug(this,DebugAll,"msgExecute. Caller: '%s'. Called: '%s'.",
caller.c_str(),called.c_str());
bool newPresence = true;
bool available = iplugin.m_presence->get(caller,called,newPresence);
if (!(newPresence || available)) {
@ -1956,9 +1959,7 @@ bool YJGDriver::msgExecute(Message& msg, String& dest)
msg.setParam("error","offline");
return false;
}
// Parameters OK. Create connection
DDebug(this,DebugAll,"msgExecute. Caller: '%s'. Called: '%s'.",
caller.c_str(),called.c_str());
// Parameters OK. Create connection and init channel
YJGConnection* conn = new YJGConnection(m_jg,&msg,caller,called,available);
Channel* ch = static_cast<Channel*>(msg.userData());
if (ch && conn->connect(ch,msg.getValue("reason"))) {