Example #1
0
// Caller must hold mLock.
void SipPresenceMonitor::notifyStateChange(UtlString& contact,
                                           SipPresenceEvent* presenceEvent)
{
   // Loop through the notifier list
   UtlHashMapIterator iterator(mStateChangeNotifiers);
   UtlString* listUri;
   StateChangeNotifier* notifier;
   Url contactUrl(contact);

   while ((listUri = dynamic_cast <UtlString *> (iterator())))
   {
      notifier = dynamic_cast <StateChangeNotifier *> (mStateChangeNotifiers.findValue(listUri));

      UtlString id;
      makeId(id, contact);
      Tuple* tuple = presenceEvent->getTuple(id);

      if (tuple)
      {
         UtlString status;
         tuple->getStatus(status);

         notifier->setStatus(contactUrl,
                             status.compareTo(STATUS_CLOSED) == 0 ?
                             StateChangeNotifier::AWAY :
                             StateChangeNotifier::PRESENT);
      }
      else
      {
         notifier->setStatus(contactUrl, StateChangeNotifier::AWAY);
      }
   }
}
Example #2
0
// Report to all the notifiers in mStateChangeNotifiers a new event
// 'dialogEvent' for AOR 'contact'.
void SipDialogMonitor::notifyStateChange(UtlString& contact,
                                         StateChangeNotifier::Status status)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange "
                 "AOR = '%s', status = %s",
                 contact.data(),
                 (status == StateChangeNotifier::ON_HOOK ? "ON_HOOK" :
                  status == StateChangeNotifier::OFF_HOOK ? "OFF_HOOK" :
                  "UNKNOWN"));
   Url contactUrl(contact);

   // Loop through the notifier list, reporting the status to the notifiers.
   UtlHashMapIterator iterator(mStateChangeNotifiers);
   UtlString* listUri;
   UtlVoidPtr* container;
   StateChangeNotifier* notifier;
   while ((listUri = dynamic_cast <UtlString *> (iterator())))
   {
      container = dynamic_cast <UtlVoidPtr *> (mStateChangeNotifiers.findValue(listUri));
      notifier = (StateChangeNotifier *) container->getValue();
      // Report the status to the notifier.
      notifier->setStatus(contactUrl, status);
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipDialogMonitor::notifyStateChange setting state to %d",
                    status);
   }
}
Example #3
0
void SipDialogMonitor::notifyStateChange(UtlString& contact, SipDialogEvent* dialogEvent)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange contact = %s",
                 contact.data());

   // Loop through the notifier list
   UtlHashMapIterator iterator(mStateChangeNotifiers);
   UtlString* listUri;
   UtlVoidPtr* container;
   StateChangeNotifier* notifier;
   Url contactUrl(contact);
   mLock.acquire();
   while (listUri = dynamic_cast <UtlString *> (iterator()))
   {
      container = dynamic_cast <UtlVoidPtr *> (mStateChangeNotifiers.findValue(listUri));
      notifier = (StateChangeNotifier *) container->getValue();

      if (dialogEvent->isEmpty())
      {
         notifier->setStatus(contactUrl, StateChangeNotifier::ON_HOOK);
         OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange dialog is empty, setting state to on hook");
      }
      else
      {
         Dialog* dialog = dialogEvent->getFirstDialog();
            
         UtlString state, event, code;
         dialog->getState(state, event, code);
            
         OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange dialog state = %s",
                       state.data());
         if (state.compareTo(STATE_CONFIRMED) == 0)
         {
            notifier->setStatus(contactUrl, StateChangeNotifier::OFF_HOOK);
            OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange setting state to off hook");
         }
         else
         {     
            if (state.compareTo(STATE_TERMINATED) == 0)
            {
               notifier->setStatus(contactUrl, StateChangeNotifier::ON_HOOK);
               OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange setting state to on hook");
            }
            else
            {
               notifier->setStatus(contactUrl, StateChangeNotifier::RINGING);
               OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::notifyStateChange setting state to ringing");
            }
         }
      }
   }
   mLock.release();
}
void AvatarQueryJob::start()
{
	d->baseDir = KUrl( KStandardDirs::locateLocal("appdata", QLatin1String("avatars") ) );

	if( d->category & Kopete::AvatarManager::User )
	{
		d->listAvatarDirectory( UserDir );
	}
	if( d->category & Kopete::AvatarManager::Contact )
	{
		KUrl contactUrl(d->baseDir);
		contactUrl.addPath( ContactDir );

		const QDir contactDir(contactUrl.toLocalFile());
		const QStringList subdirsList = contactDir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot );
		foreach(const QString &subdir, subdirsList)
		{
			d->listAvatarDirectory( ContactDir + QDir::separator() + subdir );
		}
void SipPresenceMonitor::notifyStateChange(UtlString& contact, SipPresenceEvent* presenceEvent)
{

   // Loop through the notifier list
   UtlHashMapIterator iterator(mStateChangeNotifiers);
   UtlString* listUri;
   StateChangeNotifier* notifier;
   Url contactUrl(contact);
   mLock.acquire();
   while (listUri = dynamic_cast <UtlString *> (iterator()))
   {
      notifier = dynamic_cast <StateChangeNotifier *> (mStateChangeNotifiers.findValue(listUri));

      if (presenceEvent->isEmpty())
      {
         notifier->setStatus(contactUrl, StateChangeNotifier::AWAY);
      }
      else
      {
         UtlString id;
         NetMd5Codec::encode(contact, id);
         Tuple* tuple = presenceEvent->getTuple(id);
            
         UtlString status;
         tuple->getStatus(status);
            
         if (status.compareTo(STATUS_CLOSE) == 0)
         {
            notifier->setStatus(contactUrl, StateChangeNotifier::AWAY);
         }
         else
         {     
            notifier->setStatus(contactUrl, StateChangeNotifier::PRESENT);
         }
      }
   }
   mLock.release();
}
SubscribeServerThread::SubscribeStatus SubscribeServerThread::addSubscription(
    const int timeNow,
    const SipMessage* subscribeMessage,
    const char* domain,
    const UtlString& eventType,
    const UtlString& eventId,
    const UtlHashMap& eventParams,
    UtlString& newToTag,
    int& grantedExpiration)
{
    SubscribeStatus returnStatus = STATUS_INTERNAL_ERROR;
    int subscribeCseqInt = 0;
    UtlString callId;
    UtlString contactEntry;
    UtlString to;
    UtlString from;
    UtlString route;
    UtlString key;
    UtlString method;
    Url identity;

    //  Construct the identity
    UtlString uriUser, requestUri;
    subscribeMessage->getUri( NULL, NULL, NULL, &uriUser );
    subscribeMessage->getRequestUri( &requestUri );
    identity.setUserId( uriUser );
    identity.setUrlType( "sip" );
    identity.setHostAddress( domain );

    subscribeMessage->getToField(&to);
    subscribeMessage->getFromField(&from);
    subscribeMessage->getCallIdField(&callId);
    subscribeMessage->getCSeqField(&subscribeCseqInt, &method);
    subscribeMessage->getContactEntry(0, &contactEntry);

    subscribeMessage->buildRouteField(&route);
    Url toUrl;
    subscribeMessage->getToUrl(toUrl);
    int commonExpires = -1;
    if ( subscribeMessage->getExpiresField( &commonExpires ) )
    {
       if( commonExpires > 0 ) // came from request
       {
          if (commonExpires < mMinExpiresTimeint)
          {
             returnStatus = STATUS_LESS_THAN_MINEXPIRES;
             OsSysLog::add( FAC_SIP, PRI_ERR, "addSubscription: "
                            "Expires (%d) less than Minimum (%d)",
                           commonExpires, mMinExpiresTimeint);
             return returnStatus;
          }
          else if (commonExpires > mDefaultSubscribePeriod)
          {
             commonExpires = mDefaultSubscribePeriod;
          }
          else
          {
             // commonExpires is in the allowed range - use the requested value
          }
        }
        else if( commonExpires == 0 )
        {
            // remove subscription binding
            // remove all bindings  because one contact value is *
            OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -"
                " subscription for url %s and event %s to be removed after sending NOTIFY",
                toUrl.toString().data(), eventType.data());

            returnStatus = STATUS_TO_BE_REMOVED;
            return returnStatus;
        }
        else if( commonExpires == -1) // no expires value in request
        {
            // Assume the default value
            commonExpires = mDefaultSubscribePeriod;
            OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription -"
                " No Expires Value, assigning default value (%d)", commonExpires);
        }
    }

    UtlString sipxImpliedParameter(SIPX_IMPLIED_SUB);
    UtlString* sipxImpliedDuration = NULL;

    int grantedExpirationTime;
    if ((  sipxImpliedDuration
         = dynamic_cast<UtlString*>(eventParams.findValue(&sipxImpliedParameter))))
    {
       /*
        * This request was generated by the registrar as an implied subscription;
        * its duration must therefore match that of the registration, which has
        * already been randomized.
        */
       grantedExpirationTime = atoi(sipxImpliedDuration->data());
    }
    else
    {
       /*
        * The request is for a new or refreshed subscription (other cases were handled above);
        * commonExpires is now the requested duration in the range:
        *    mMinExpiresTimeint <= commonExpires <= mDefaultSubscribePeriod
        * In order to distribute expirations smoothly, we actually grant a randomized duration
        */
       int spreadFloor = mMinExpiresTimeint*2;

       if ( commonExpires > spreadFloor )
       {
          // a normal (long) registration
          // - spread it between twice the min and the longest they asked for
          grantedExpirationTime = (  (rand() % (commonExpires - spreadFloor))
                                   + spreadFloor);
       }
       else if ( commonExpires > mMinExpiresTimeint )
       {
          // a short but not minimum registration
          // - spread it between the min and the longest they asked for
          grantedExpirationTime = (  (rand()
                                      % (commonExpires - mMinExpiresTimeint)
                                      )
                                   + mMinExpiresTimeint
                                   );
       }
       else // longestExpiration == mMinExpiresTimeint
       {
          // minimum - can't randomize because we can't shorten or lengthen it
          grantedExpirationTime = mMinExpiresTimeint;
       }
    }

    // Handle the to-tag:
    // If no to-tag, this is a new subscription, for which we must create
    // a to-tag.
    // If there is a to-tag, this is a renewal of a subscription, and we
    // must first check that the subscription exists.  (This is because if
    // the UA thinks there is a subscription, but we do not know of it, we
    // cannot reconstitute the subscription, as we do not know the NOTIFY CSeq
    // that the UA expects.  See XECS-406 for the ill consequences of
    // this problem.)

    // Clear the returned new to-tag.
    newToTag.remove(0);
    {
       UtlString x;
       bool r = toUrl.getFieldParameter("tag", x);
       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription getting to-tag, return %d, value '%s'",
                     (int) r, x.data());
    }
    UtlString toTag;
    if (toUrl.getFieldParameter("tag", toTag))
    {
       // Check to see if this subscription exists.
       // Critical Section here
       OsLock mutex(mLock);

       bool exists = SubscriptionDB::getInstance()->subscriptionExists(
          SUBSCRIPTION_COMPONENT_STATUS,
          to, from, callId, OsDateTime::getSecsSinceEpoch());

       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription subscriptionExists(..., '%s', '%s', '%s', %d) = %d",
                     to.data(), from.data(),
                     callId.data(), (int) OsDateTime::getSecsSinceEpoch(),
                     exists);

       if (!exists)
       {
          returnStatus = STATUS_BAD_SUBSCRIPTION;
          return returnStatus;
       }
    }
    else
    {
       // Generate a random to-tag.
       CallId::getNewTag(newToTag);
       // Add it to the remembered To header value.
       to.append(";tag=");
       to.append(newToTag);
       OsSysLog::add(FAC_SIP, PRI_DEBUG,"SubscribeServerThread::addSubscription generated to-tag '%s'",
                     newToTag.data());
    }

    OsSysLog::add(FAC_SIP, PRI_DEBUG,
                  "SubscribeServerThread::addSubscription -"
                  " Adding/updating subscription for URI '%s' event %s duration %d to '%s'",
                  toUrl.toString().data(), eventType.data(), grantedExpirationTime, contactEntry.data());

    // trim the contact to just the uri
    Url contactUrl(contactEntry);
    contactUrl.getUri(contactEntry);

    // add bindings
    identity.getIdentity( key );

    // Insert or update the information for this subscription.
    // (Note that the "notify CSeq" parameter is ignored if there is
    // an existing SubscriptionDB row for this subscription.)
    if (insertRow(requestUri, // identity,
                  callId,
                  contactEntry,
                  grantedExpirationTime + timeNow,
                  subscribeCseqInt,
                  eventType,
                  eventId,
                  to,
                  from,
                  key,                 // this will be searched for later
                  route,
                  1))                  // initial notify cseq (sent to phone)
    {
       grantedExpiration = grantedExpirationTime;
       returnStatus = STATUS_SUCCESS;
    }
    else
    {
       // log the error and send error indication to subscriber
       OsSysLog::add(FAC_SIP, PRI_ERR,
                     "SubscribeServerThread::addSubscription -"
                     " Could not insert record in Database");

       returnStatus = STATUS_INTERNAL_ERROR;
    }

    return returnStatus;
}
Example #7
0
   void testBranchIdUniqueness()
      {
#        define CASES 10
         // The test succeeds if at least 9 of the 16 digits differ between all
         // pairs of Call-Ids we generate.  If the generated Call-Ids are random, this
         // test will fail 0.00023% of the time for any one pair, or about 0.011%
         // of the time for one of the 45 pairs.
#        define MIN_DIFFS 9

         UtlString stableTestSecret("stable");
         BranchId::setSecret(stableTestSecret);

         const char* testMsg =
            "INVITE sip:[email protected] SIP/2.0"
            "To: sip:[email protected]\r\n"
            "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n"
            "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n"
            "Cseq: 1 INVITE\r\n"
            "Max-Forwards: 20\r\n"
            "Contact: [email protected]\r\n"
            "Content-Length: 0\r\n"
            "\r\n";

         SipMessage sipMsg(testMsg);

         UtlString output[CASES];

         // Generate some BranchIds.
         Os::Logger::instance().log(FAC_SIP,PRI_DEBUG,"BranchIdTest::testBranchIdUniqueness unique cases");
         for (int i = 0; i < CASES; i++)
         {
            BranchId branchId(sipMsg);
            output[i].append(branchId.data());

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "case %d initial: %s\n", i, output[i].data());
         }

         // Compare that they're different enough.
         for (int i = 0; i < CASES; i++)
         {
            for (int j = i+1; j < CASES; j++)
            {
               UtlString* s1 = &output[i];
               UtlString* s2 = &output[j];

               int differences = 0;
               for (size_t k = 0; k < s1->length() && k < s1->length(); k++)
               {
                  if ((*s1)(k) != (*s2)(k))
                  {
                     differences++;
                  }
               }
               if (differences < MIN_DIFFS)
               {
                  char msg[200];
                  sprintf(msg,
                          "BranchId '%s' and '%s' have %d different characters, "
                          "which is less than the minimum, %d",
                          s1->data(), s2->data(), differences, MIN_DIFFS);
                  CPPUNIT_ASSERT_MESSAGE(msg, FALSE);
               }
            }
         }

         // Now regenerate those as child ids without forks
         Os::Logger::instance().log(FAC_SIP,PRI_DEBUG,"BranchIdTest::testBranchIdUniqueness child cases");
         for (int i = 0; i < CASES; i++)
         {
            BranchId parentBranchId(output[i]);
            // no addFork calls before creating the child
            BranchId branchId(parentBranchId, sipMsg);
            output[i].remove(0);
            output[i].append(branchId.data());

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "case %d child  : %s\n", i, output[i].data());
         }

         // Compare that they're different enough.
         for (int i = 0; i < CASES; i++)
         {
            for (int j = i+1; j < CASES; j++)
            {
               UtlString* s1 = &output[i];
               UtlString* s2 = &output[j];

               int differences = 0;
               for (size_t k = 0; k < s1->length() && k < s1->length(); k++)
               {
                  if ((*s1)(k) != (*s2)(k))
                  {
                     differences++;
                  }
               }
               if (differences < MIN_DIFFS)
               {
                  char msg[200];
                  sprintf(msg,
                          "BranchId '%s' and '%s' have %d different characters, "
                          "which is less than the minimum, %d",
                          s1->data(), s2->data(), differences, MIN_DIFFS);
                  CPPUNIT_ASSERT_MESSAGE(msg, FALSE);
               }
            }
         }

         // And then add a fork to each to see if the forks are different
         Os::Logger::instance().log(FAC_SIP,PRI_DEBUG,"BranchIdTest::testBranchIdUniqueness forked cases");
         for (int i = 0; i < CASES; i++)
         {
            BranchId parentBranchId(output[i]);

            char forkContact[32];
            sprintf(forkContact, "sip:someuser%02d@domain", i);
            Url contactUrl(forkContact);

            parentBranchId.addFork(contactUrl);

            BranchId branchId(parentBranchId, sipMsg);
            output[i].remove(0);
            output[i].append(branchId.data());

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "case %d forked : %s\n", i, output[i].data());
         }

         // Compare that they're different enough.
         for (int i = 0; i < CASES; i++)
         {
            for (int j = i+1; j < CASES; j++)
            {
               UtlString* s1 = &output[i];
               UtlString* s2 = &output[j];

               int differences = 0;
               for (size_t k = 0; k < s1->length() && k < s1->length(); k++)
               {
                  if ((*s1)(k) != (*s2)(k))
                  {
                     differences++;
                  }
               }
               if (differences < MIN_DIFFS)
               {
                  char msg[200];
                  sprintf(msg,
                          "BranchId '%s' and '%s' have %d different characters, "
                          "which is less than the minimum, %d",
                          s1->data(), s2->data(), differences, MIN_DIFFS);
                  CPPUNIT_ASSERT_MESSAGE(msg, FALSE);
               }
            }
         }
      }
Example #8
0
ProvisioningAttrList* XmlRpcSignIn::Action(ProvisioningAttrList& rRequestAttributes)
{
   ProvisioningAttrList* pResponse;
   UtlString             uriString;
   UtlString             status;

   osPrintf("{method} = action\n{object-class} = login\n");
   rRequestAttributes.dumpAttributes();
   osPrintf("\n");

   // Extract the action attribute from the request
   // operate on either sign-in or sign-out attributes
   if (rRequestAttributes.getAttribute(XMLRPC_SIGN_IN_TAG, uriString)) {
      // See if the Agent is not already signed-in
      Url contactUrl(uriString);
      mpSipPresenceMonitor->getState(contactUrl, status);
      if (status.compareTo(STATUS_OPEN) == 0) {
         // Already signed-in, return error
         pResponse = new ProvisioningAttrList;
         pResponse->setAttribute("method-name", "action");
         pResponse->setAttribute("result-code", ProvisioningAgent::SUCCESS);
         pResponse->setAttribute("result-text", "SUCCESS: User already signed-in");
         return pResponse;
      }
      
      // Sign-in the Agent
      mpSipPresenceMonitor->setStatus(contactUrl, StateChangeNotifier::PRESENT);

      // Build up the response.
      pResponse = new ProvisioningAttrList;
      pResponse->setAttribute("method-name", "action");
      pResponse->setAttribute("result-code", ProvisioningAgent::SUCCESS);
      pResponse->setAttribute("result-text", "SUCCESS: sign-in");
      return pResponse;
   }
   else if (rRequestAttributes.getAttribute(XMLRPC_SIGN_OUT_TAG, uriString)) {
      // See if the Agent is not already signed-out
      Url contactUrl(uriString);
      mpSipPresenceMonitor->getState(contactUrl, status);
      if (status.compareTo(STATUS_CLOSED) == 0) {
         // Already signed-out, return error
         pResponse = new ProvisioningAttrList;
         pResponse->setAttribute("method-name", "action");
         pResponse->setAttribute("result-code", ProvisioningAgent::SUCCESS);
         pResponse->setAttribute("result-text", "SUCCESS: User already signed-out");
         return pResponse;
      }
      
      // Sign-out the Agent
      mpSipPresenceMonitor->setStatus(contactUrl, StateChangeNotifier::AWAY);

      // Build up the response.
      pResponse = new ProvisioningAttrList;
      pResponse->setAttribute("method-name", "action");
      pResponse->setAttribute("result-code", ProvisioningAgent::SUCCESS);
      pResponse->setAttribute("result-text", "SUCCESS: sign-out");
      return pResponse;
   }
   else if (rRequestAttributes.getAttribute(XMLRPC_SIGN_IN_STATUS_TAG, uriString)) {
      // Get the Agent status
      Url contactUrl(uriString);
      mpSipPresenceMonitor->getState(contactUrl, status);

      // Build up the response.
      pResponse = new ProvisioningAttrList;
      pResponse->setAttribute("method-name", "action");
      pResponse->setAttribute("result-code", ProvisioningAgent::SUCCESS);
      pResponse->setAttribute("result-text", status);
      return pResponse;
   }
   else {
      // Unrecognized or missing action-object
      pResponse = new ProvisioningAttrList;
      pResponse->setAttribute("method-name", "action");
      pResponse->setAttribute("result-code", ProvisioningAgent::FAILURE);
      pResponse->setAttribute("result-text", "Invalid action operation");
      return pResponse;
   }
}