⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuim.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
      {
         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 + -