Exemplo n.º 1
0
// Update the subscriptions we maintain to agree with the current contact state
void ContactSet::updateSubscriptions()
{
   OsSysLog::add(FAC_RLS, PRI_DEBUG,
                 "ContactSet::updateSubscriptions mUri = '%s'",
                 mUri.data());

   // First, scan mSubscriptions to construct a list of all the
   // call-id/contact combinations.
   // (If a phone reboots and starts registering with a different Call-Id,
   // the call-id/contact combination will be different even if the contact
   // URI is unchanged.  So the new registration will appear to be different
   // to this machinery, and it will establish a new SubscriptionSet to
   // the contact URI.  This compensates for the fact that the previous
   // SubscriptionSet to the contact URI appears to the RLS to be
   // working but the phone no longer knows of the subscription.  The
   // reg events will eventually terminate the old combination and we
   // will delete its SubscriptionSet.)
   UtlHashBag callid_contacts;

   UtlHashMapIterator subs_itor(mSubscriptions);
   while (subs_itor())
   {
      if (OsSysLog::willLog(FAC_RLS, PRI_DEBUG))
      {
         OsSysLog::add(FAC_RLS, PRI_DEBUG,
                       "ContactSet::updateSubscriptions subscription '%s'",
                       (dynamic_cast <UtlString*> (subs_itor.key()))->data());
      }
      UtlHashMap* contact_state =
         dynamic_cast <UtlHashMap*> (subs_itor.value());
      OsSysLog::add(FAC_RLS, PRI_DEBUG,
                    "ContactSet::updateSubscriptions contact_state = %p",
                    contact_state);
      UtlHashMapIterator contact_itor(*contact_state);
      while (contact_itor())
      {
         UtlString* contact =
            dynamic_cast <UtlString*> (contact_itor.value());
         if (OsSysLog::willLog(FAC_RLS, PRI_DEBUG))
         {
            OsSysLog::add(FAC_RLS, PRI_DEBUG,
                          "ContactSet::updateSubscriptions contact id '%s', Call-Id/URI '%s'",
                          (dynamic_cast <UtlString*> (contact_itor.key()))->data(),
                          contact->data());
         }
         // Check if the contact is already in callid_contacts.
         if (!callid_contacts.find(contact))
         {
            // If not, add it.
            UtlString* c = new UtlString(*contact);
            callid_contacts.insert(c);
            OsSysLog::add(FAC_RLS, PRI_DEBUG,
                          "ContactSet::updateSubscriptions contact added");
         }
      }
   }

   // If the list of callid_contacts is empty, add mUri as the default contact
   // (with an empty registration Call-Id).
   if (callid_contacts.isEmpty())
   {
      OsSysLog::add(FAC_RLS, PRI_DEBUG,
                    "ContactSet::updateSubscriptions adding default contact mUri = '%s'",
                    mUri.data());
      UtlString* c = new UtlString(";");
      c->append(mUri);
      callid_contacts.insert(c);
   }

   // Now that we have a clean list of callid_contacts, update
   // SubscriptionSets to match it.

   // If we both terminate subscriptions and create subscriptions,
   // wait a short while to allow the terminations to complete.  This
   // should not be necessary, but it makes life easier on Polycom
   // phones which (at this time) cannot support two subscriptions at
   // a time, and if the termination of the old subscription arrives
   // after the initiation of the new subscription, the new
   // subscription will be lost.
   // This variable tracks whether such a wait is needed before a
   // subscription is started.
   bool subscription_ended_but_no_wait_done_yet = false;

   // Iterate through the list of SubscriptionSets and remove any that aren't
   // in callid_contacts.
   {
      UtlHashMapIterator itor(mSubscriptionSets);
      UtlString* ss;
      while ((ss = dynamic_cast <UtlString*> (itor())))
      {
         if (!callid_contacts.find(ss))
         {
            OsSysLog::add(FAC_RLS, PRI_DEBUG,
                          "ContactSet::updateSubscriptions deleting subscription for '%s' in mUri = '%s'",
                          ss->data(), mUri.data());
            mSubscriptionSets.destroy(ss);
	    subscription_ended_but_no_wait_done_yet = true;
         }
      }
   }

   // Iterate through callid_contacts and add a SubscriptionSet for
   // any that aren't in mSubscriptionSets.
   // We don't limit the number of additions here, as the size of
   // callid_contacts is guarded by the tests in notifyEventCallback.
   {
      UtlHashBagIterator itor(callid_contacts);
      UtlString* callid_contact;
      while ((callid_contact = dynamic_cast <UtlString*> (itor())))
      {
         if (!mSubscriptionSets.find(callid_contact))
         {
	    // If we both terminate subscriptions and create subscriptions,
	    // wait a short while to allow the terminations to complete.
            // Note that this wait must be no more than the bulk add/delete
            // change delay, as that is how fast ResourceListFileReader
            // generates requests to the ResourceListServer task.
            int wait = getResourceListServer()->getChangeDelay();
            if (wait > 0)
            {
               if (subscription_ended_but_no_wait_done_yet)
               {
                  OsSysLog::add(FAC_RLS, PRI_DEBUG,
                                "ContactSet::updateSubscriptions waiting for %d msec",
                                wait);
                  OsTask::delay(wait);
                  subscription_ended_but_no_wait_done_yet = false;
               }
            }

            OsSysLog::add(FAC_RLS, PRI_DEBUG,
                          "ContactSet::updateSubscriptions adding subscription for '%s' in mUri = '%s'",
                          callid_contact->data(), mUri.data());
            // Get the contact URI into a UtlString.
            UtlString uri(callid_contact->data() +
                          callid_contact->index(';') +
                          1);
            mSubscriptionSets.insertKeyAndValue(new UtlString(*callid_contact),
                                                new SubscriptionSet(mResource,
                                                                    uri));
         }
      }
   }

   // Free callid_contacts.
   callid_contacts.destroyAll();
}
Exemplo n.º 2
0
// Update the subscriptions we maintain to agree with the current contact state
void AppearanceGroup::updateSubscriptions()
{
   Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                 "AppearanceGroup::updateSubscriptions mUri = '%s'",
                 mSharedUser.data());

   // First, scan mSubscriptions to construct a list of all the
   // call-id/contact combinations.
   // (If a phone reboots and starts registering with a different Call-Id,
   // the call-id/contact combination will be different even if the contact
   // URI is unchanged.  So the new registration will appear to be different
   // to this machinery, and it will establish a new Appearance to
   // the contact URI.  This compensates for the fact that the previous
   // Appearance to the contact URI appears to the Appearance Agent to be
   // working but the phone no longer knows of the subscription.  The
   // reg events will eventually terminate the old combination and we
   // will delete its Appearance.)
   UtlHashBag callid_contacts;

   UtlHashMapIterator subs_itor(mSubscriptions);
   while (subs_itor())
   {
      if (Os::Logger::instance().willLog(FAC_SAA, PRI_DEBUG))
      {
         Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                       "AppearanceGroup::updateSubscriptions subscription '%s'",
                       (dynamic_cast <UtlString*> (subs_itor.key()))->data());
      }
      UtlHashMap* contact_state =
         dynamic_cast <UtlHashMap*> (subs_itor.value());
      Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                    "AppearanceGroup::updateSubscriptions contact_state = %p",
                    contact_state);
      UtlHashMapIterator contact_itor(*contact_state);
      while (contact_itor())
      {
         UtlString* contact =
            dynamic_cast <UtlString*> (contact_itor.value());
         if (Os::Logger::instance().willLog(FAC_SAA, PRI_DEBUG))
         {
            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions contact id '%s', Call-Id/URI '%s'",
                          (dynamic_cast <UtlString*> (contact_itor.key()))->data(),
                          contact->data());
         }
         // Check if the contact is already in callid_contacts.
         if (!callid_contacts.find(contact))
         {
            // If not, add it.
            UtlString* c = new UtlString(*contact);
            callid_contacts.insert(c);
            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions contact '%s' added", c->data());
         }
      }
   }

   // Now that we have a clean list of callid_contacts, update
   // Appearances to match it.

   // If we both terminate subscriptions and create subscriptions,
   // wait a short while to allow the terminations to complete.  This
   // should not be necessary, but it makes life easier on Polycom
   // phones which (at this time) cannot support two subscriptions at
   // a time, and if the termination of the old subscription arrives
   // after the initiation of the new subscription, the new
   // subscription will be lost.
   // This variable tracks whether such a wait is needed before a
   // subscription is started.
   bool subscription_ended_but_no_wait_done_yet = false;

   // Iterate through the list of Appearances and remove any that aren't
   // in callid_contacts.
   {
      UtlHashMapIterator itor(mAppearances);
      UtlString* ss;
      while ((ss = dynamic_cast <UtlString*> (itor())))
      {
         if (!callid_contacts.find(ss))
         {
            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions deleting subscription for '%s' in mUri = '%s'",
                          ss->data(), mSharedUser.data());
            // Terminate all dialogs for this Appearance, then publish - before we delete it
            bool bContentChanged = false;
            SipDialogEvent* lPartialContent = new SipDialogEvent("partial", mSharedUser.data());
            Appearance* inst = dynamic_cast <Appearance*> (itor.value());
            bContentChanged = inst->terminateDialogs(true); // terminate all dialogs
            inst->getDialogs(lPartialContent);
            if (bContentChanged)
            {
               lPartialContent->buildBody();
               publish(true, true, lPartialContent);
               delete lPartialContent;
            }
            mAppearances.destroy(ss);
            subscription_ended_but_no_wait_done_yet = true;
         }
         else
         {
            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions found subscription for '%s' in mUri = '%s'",
                          ss->data(), mSharedUser.data());
         }
      }
   }

   // Iterate through callid_contacts and add an Appearance for
   // any that aren't in mAppearances.
   // We don't limit the number of additions here, as the size of
   // callid_contacts is guarded by the tests in notifyEventCallback.
   {
      UtlHashBagIterator itor(callid_contacts);
      UtlString* callid_contact;
      while ((callid_contact = dynamic_cast <UtlString*> (itor())))
      {
         if (!mAppearances.find(callid_contact))
         {
            // If we both terminate subscriptions and create subscriptions,
            // wait a short while to allow the terminations to complete.
            if (SUBSCRIPTION_WAIT > 0)
            {
               if (subscription_ended_but_no_wait_done_yet)
               {
                  Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                                "AppearanceGroup::updateSubscriptions waiting for %d msec",
                                SUBSCRIPTION_WAIT);
                  OsTask::delay(SUBSCRIPTION_WAIT);
                  subscription_ended_but_no_wait_done_yet = false;
               }
            }

            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions adding subscription for '%s' in mUri = '%s'",
                          callid_contact->data(), mSharedUser.data());
            // Get the contact URI into a UtlString.
            UtlString uri(callid_contact->data() +
                          callid_contact->index(';') +
                          1);
            mAppearances.insertKeyAndValue(new UtlString(*callid_contact),
                                           new Appearance(getAppearanceAgent(), this,  uri)
                                           );
         }
         else
         {
            Os::Logger::instance().log(FAC_SAA, PRI_DEBUG,
                          "AppearanceGroup::updateSubscriptions using existing subscription for '%s' in mUri = '%s'",
                          callid_contact->data(), mSharedUser.data());
         }
      }
   }

   // Free callid_contacts.
   callid_contacts.destroyAll();
}