void BOSHConnectionPool::handleConnectFinished(bool error, BOSHConnection::ref connection) { if (error) { onSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition)); /*TODO: We can probably manage to not terminate the stream here and use the rid/ack retry * logic to just swallow the error and try again (some number of tries). */ } else { if (sid.empty()) { connection->startStream(to, rid); } if (pendingRestart) { restartStream(); } tryToSendQueuedData(); } }
void BOSHConnection::handleDataRead(std::shared_ptr<SafeByteArray> data) { onBOSHDataRead(*data); buffer_ = concat(buffer_, *data); std::string response = safeByteArrayToString(buffer_); if (response.find("\r\n\r\n") == std::string::npos) { onBOSHDataRead(createSafeByteArray("[[Previous read incomplete, pending]]")); return; } std::string httpCode = response.substr(response.find(" ") + 1, 3); if (httpCode != "200") { onHTTPError(httpCode); return; } BOSHBodyExtractor parser(parserFactory_, createByteArray(response.substr(response.find("\r\n\r\n") + 4))); if (parser.getBody()) { if (parser.getBody()->attributes.getAttribute("type") == "terminate") { BOSHError::Type errorType = parseTerminationCondition(parser.getBody()->attributes.getAttribute("condition")); onSessionTerminated(errorType == BOSHError::NoError ? std::shared_ptr<BOSHError>() : std::make_shared<BOSHError>(errorType)); } buffer_.clear(); if (waitingForStartResponse_) { waitingForStartResponse_ = false; sid_ = parser.getBody()->attributes.getAttribute("sid"); std::string requestsString = parser.getBody()->attributes.getAttribute("requests"); size_t requests = 2; if (!requestsString.empty()) { try { requests = boost::lexical_cast<size_t>(requestsString); } catch (const boost::bad_lexical_cast&) { } } onSessionStarted(sid_, requests); } SafeByteArray payload = createSafeByteArray(parser.getBody()->content); /* Say we're good to go again, so don't add anything after here in the method */ pending_ = false; onXMPPDataRead(payload); } }
void JingleSession::setInitiated(IJingleApplication *AApplication) { FStatus=IJingle::Initiated; disconnect(parent()); setParent(AApplication->instance()); connect(this,SIGNAL(sessionInitiated(Jid,QString)),parent(),SLOT(onSessionInitiated(Jid,QString))); connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(),SLOT(onSessionAccepted(Jid,QString))); connect(this,SIGNAL(sessionConnected(Jid,QString)),parent(),SLOT(onSessionConnected(Jid,QString))); connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason))); connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement))); connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString))); connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason))); emit sessionInitiated(FThisParty, FSid); }
JingleSession::JingleSession(const JingleStanza &AStanza): FValid(false),FOutgoing(false),FThisParty(AStanza.to()),FOtherParty(AStanza.from()),FActionId(),FAction(IJingle::NoAction) { QDomElement jingle=AStanza.firstElement("jingle", NS_JINGLE); if (!jingle.isNull()) { QString action=jingle.attribute("action"); if (action=="session-initiate") { FSid=jingle.attribute("sid"); for (QDomElement content=jingle.firstChildElement("content"); !content.isNull(); content=content.nextSiblingElement("content")) { QDomElement description=content.firstChildElement("description"); if (!description.isNull()) { FApplicationNamespace = description.namespaceURI(); QDomElement transport=content.firstChildElement("transport"); if (!transport.isNull()) { setParent(FJingle->appByNS(FApplicationNamespace)->instance()); if (!addContent(content.attribute("name"), description, transport, content.attribute("initiator")==QString("responder"))) qWarning() << "addContent() failed!"; FValid=true; connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(), SLOT(onSessionAccepted(Jid,QString))); connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason))); connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement))); connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString))); connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason))); } } } if (!FSessions.contains(FThisParty) || !FSessions[FThisParty].contains(FSid)) FSessions[FThisParty].insert(FSid, this); else qWarning() << "Session exists!"; } } }
JingleSession::JingleSession(const Jid &AThisParty, const Jid &AOtherParty, const QString &AApplicationNS): QObject(FJingle->appByNS(AApplicationNS)->instance()),FValid(false), FOutgoing(true), FApplicationNamespace(AApplicationNS),FThisParty(AThisParty), FOtherParty(AOtherParty), FSid(getSid(AThisParty)), FActionId(), FAction(IJingle::NoAction), FReason(IJingle::NoReason) { FSessions[FThisParty].insert(FSid, this); if (FThisParty.isValid() && FOtherParty.isValid()) { FValid=true; connect(this,SIGNAL(sessionInitiated(Jid,QString)),parent(),SLOT(onSessionInitiated(Jid,QString))); connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(),SLOT(onSessionAccepted(Jid,QString))); connect(this,SIGNAL(sessionConnected(Jid,QString)),parent(),SLOT(onSessionConnected(Jid,QString))); connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason))); connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement))); connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString))); connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason))); } }