📄 tuim.cxx
字号:
{
if ( i->dialog->getCallId() == id )
{
i = mPages.erase( i );
}
}
}
}
void
TuIM::processSubscribeResponse(SipMessage* msg, Buddy& buddy)
{
int number = msg->header(h_StatusLine).responseCode();
Uri to = msg->header(h_To).uri();
InfoLog ( << "subscribe got response " << number << " from " << to );
if ( (number>=200) && (number<300) )
{
int expires = mSubscriptionTimeSeconds;
if ( msg->exists(h_Expires) )
{
expires = msg->header(h_Expires).value();
}
if ( expires < 15 )
{
InfoLog( << "Got very small expiers of " << expires );
expires = 15;
}
assert( buddy.presDialog );
buddy.presDialog->createDialogAsUAC( *msg );
buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( expires*1000 );
}
if ( (number>=300) && (number<400) )
{
ParserContainer<NameAddr>::iterator dest = msg->header(h_Contacts).begin();
while ( dest != msg->header(h_Contacts).end() )
{
DebugLog(<< "Got a 3xx to" << *dest );
Uri uri = dest->uri();
addBuddy( uri , buddy.group );
buddy.mNextTimeToSubscribe = Timer::getForever();
dest++;
}
}
if ( (number>=400) )
{
DebugLog( << "Got an error to some subscription" );
// take this buddy off line
Uri to = msg->header(h_To).uri();
assert( mCallback );
bool changed = true;
for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++)
{
Uri u = i->uri; // getBuddyUri(i);
if ( u.getAor() == to.getAor() )
{
if ( i->online == false )
{
changed = false;
}
i->online = false;
}
}
if ( changed )
{
mCallback->presenceUpdate( to, false, Data::Empty );
}
// try to contact this buddy again later
buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 );
}
}
void
TuIM::process()
{
assert( mStack );
UInt64 now = Timer::getTimeMs();
// check if register needs refresh
if ( now > mNextTimeToRegister )
{
if ( mRegistrationDialog.isCreated() )
{
auto_ptr<SipMessage> msg( mRegistrationDialog.makeRegister() );
msg->header(h_Expires).value() = mRegistrationTimeSeconds;
setOutbound( *msg );
mStack->send( *msg );
}
mNextTimeToRegister = Timer::getRandomFutureTimeMs( mRegistrationTimeSeconds*1000 );
}
// check if any subscribes need refresh
for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++)
{
if ( now > i->mNextTimeToSubscribe )
{
Buddy& buddy = *i;
buddy.mNextTimeToSubscribe
= Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 );
assert( buddy.presDialog );
if ( buddy.presDialog->isCreated() )
{
auto_ptr<SipMessage> msg( buddy.presDialog->makeSubscribe() );
msg->header(h_Event).value() = Data("presence");;
msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") );
msg->header(h_Expires).value() = mSubscriptionTimeSeconds;
setOutbound( *msg );
mStack->send( *msg );
}
else
{
// person was not available last time - try to subscribe now
subscribeBuddy( buddy );
}
}
}
// TODO - go and clean out any subscrption to us that have expired
// check for any messages from the sip stack
SipMessage* msg( mStack->receive() );
if ( msg )
{
DebugLog ( << "got message: " << *msg);
if ( msg->isResponse() )
{
processResponse( msg );
}
if ( msg->isRequest() )
{
processRequest( msg );
}
delete msg; msg=0;
}
}
void
TuIM::registerAor( const Uri& uri, const Data& password )
{
mRegistrationPassword = password;
//const NameAddr aorName;
//const NameAddr contactName;
//aorName.uri() = uri;
//contactName.uri() = mContact;
//SipMessage* msg = Helper::makeRegister(aorName,aorName,contactName);
auto_ptr<SipMessage> msg( mRegistrationDialog.makeInitialRegister(NameAddr(uri),NameAddr(uri)) );
msg->header(h_Expires).value() = mRegistrationTimeSeconds;
msg->header(h_Contacts).front().param(p_expires) = mRegistrationTimeSeconds;
Token t;
t = Token(Data("presence"));
msg->header(h_AllowEvents).push_back( t );
mNextTimeToRegister = Timer::getRandomFutureTimeMs( mRegistrationTimeSeconds*1000 );
setOutbound( *msg );
mStack->send( *msg );
}
int
TuIM::getNumBuddies() const
{
return int(mBuddies.size());
}
const Uri
TuIM::getBuddyUri(const int index)
{
assert( index >= 0 );
assert( index < getNumBuddies() );
return mBuddies[index].uri;
}
const Data
TuIM::getBuddyGroup(const int index)
{
assert( index >= 0 );
assert( index < getNumBuddies() );
return mBuddies[index].group;
}
bool
TuIM::getBuddyStatus(const int index, Data* status)
{
assert( index >= 0 );
assert( index < getNumBuddies() );
if (status)
{
*status = mBuddies[index].status;
}
bool online = mBuddies[index].online;
return online;
}
void
TuIM::subscribeBuddy( Buddy& buddy )
{
// subscribe to this budy
auto_ptr<SipMessage> msg( buddy.presDialog->makeInitialSubscribe(NameAddr(buddy.uri),NameAddr(mAor)) );
msg->header(h_Event).value() = Data("presence");;
msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") );
msg->header(h_Expires).value() = mSubscriptionTimeSeconds;
buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 );
setOutbound( *msg );
mStack->send( *msg );
}
void
TuIM::addBuddy( const Uri& uri, const Data& group )
{
Buddy buddy;
buddy.uri = uri;
buddy.online = false;
buddy.status = Data::Empty;
buddy.group = group;
buddy.presDialog = new DeprecatedDialog( NameAddr(mContact) );
assert( buddy.presDialog );
subscribeBuddy( buddy );
mBuddies.push_back( buddy );
}
void
TuIM::removeBuddy( const Uri& name)
{
TuIM::BuddyIterator i;
i = mBuddies.begin();
while ( i != mBuddies.end() )
{
Uri u = i->uri;
if ( u.getAor() == name.getAor() )
{
// remove this buddy
// !cj! - should unsubscribe
i = mBuddies.erase(i);
}
else
{
i++;
}
}
}
void
TuIM::sendNotify(DeprecatedDialog* dialog)
{
assert( dialog );
auto_ptr<SipMessage> msg( dialog->makeNotify() );
Pidf* pidf = new Pidf( *mPidf );
msg->header(h_Event).value() = "presence";
Token state;
state.value() = Data("active");
state.param(p_expires) = dialog->getExpirySeconds();
msg->header(h_SubscriptionState) = state;
msg->setContents( pidf );
setOutbound( *msg );
mStack->send( *msg );
}
void
TuIM::sendPublish(StateAgent& sa)
{
assert( sa.dialog );
auto_ptr<SipMessage> msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) );
Pidf* pidf = new Pidf( *mPidf );
msg->header(h_Event).value() = "presence";
msg->setContents( pidf );
setOutbound( *msg );
mStack->send( *msg );
}
void
TuIM::authorizeSubscription( const Data& user )
{
// TODO implement this
}
void
TuIM::setMyPresence( const bool open, const Data& status, const Data& user )
{
// TODO implement the pser user status (when user is not empty)
assert( mPidf );
mPidf->setSimpleStatus( open, status, mContact.getAor() );
for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++)
{
DeprecatedDialog* dialog = i->dialog;
assert( dialog );
sendNotify(dialog);
}
for ( StateAgentIterator i=mStateAgents.begin(); i != mStateAgents.end(); i++)
{
sendPublish( *i );
}
}
void
TuIM::setOutboundProxy( const Uri& uri )
{
InfoLog( << "Set outbound proxy to " << uri );
mOutboundProxy = uri;
}
void
TuIM::setUAName( const Data& name )
{
DebugLog( << "Set User Agent Name to " << name );
mUAName = name;
}
void
TuIM::setOutbound( SipMessage& msg )
{
if ( msg.isResponse() )
{
return;
}
if ( !mOutboundProxy.host().empty() )
{
NameAddr proxy( mOutboundProxy );
msg.header(h_Routes).push_front( proxy );
}
if ( !mUAName.empty() )
{
DebugLog( << "UserAgent name=" << mUAName );
msg.header(h_UserAgent).value() = mUAName;
}
if ( mDefaultProtocol != UNKNOWN_TRANSPORT )
{
if ( ! msg.header(h_RequestLine).uri().exists(p_transport) )
{
switch ( mDefaultProtocol )
{
case UDP:
msg.header(h_RequestLine).uri().param(p_transport) = Symbols::UDP;
break;
case TCP:
msg.header(h_RequestLine).uri().param(p_transport) = Symbols::TCP;
break;
case TLS:
msg.header(h_RequestLine).uri().param(p_transport) = Symbols::TLS;
break;
default:
assert(0);
}
}
}
}
void
TuIM::setDefaultProtocol( TransportType protocol )
{
mDefaultProtocol = protocol;
}
void
TuIM::addStateAgent( const Uri& uri )
{
StateAgent sa;
sa.dialog = new DeprecatedDialog( NameAddr(mContact) );
sa.uri = uri;
mStateAgents.push_back( sa );
sendPublish( sa );
}
bool
TuIM::Callback::authorizeSubscription( const Uri& user )
{
return true;
}
/* ====================================================================
* 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 provi
ded 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/>.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -