bool SipPresenceMonitor::removeExtension(UtlString& groupName, Url& contactUrl)
{
   bool result = false;
   mLock.acquire();
   // Check whether the group has existed or not. If not, return false.
   SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName));
   if (list == NULL)
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::removeExtension group %s does not exist",
                    groupName.data());   
   }
   else
   {
      // Check whether the contact has existed or not
      UtlString resourceId;
      contactUrl.getIdentity(resourceId);
      Resource* resource = list->getResource(resourceId);
      if (resource)
      {
         resource = list->removeResource(resource);
         delete resource;
         
         result = true;
      }
      else
      {
         OsSysLog::add(FAC_LOG, PRI_WARNING,
                       "SipPresenceMonitor::removeExtension subscription for contact %s does not exists.",
                       resourceId.data());
      }
   }

   mLock.release();   
   return result;   
}
void SipDialogMonitor::publishContent(UtlString& contact,
                                      SipDialogEvent* dialogEvent)
{
   // Loop through all the resource lists
   UtlHashMapIterator iterator(mMonitoredLists);
   UtlString* listUri;
   SipResourceList* list;
   Resource* resource;
   UtlString id, state;
   while ((listUri = dynamic_cast <UtlString *> (iterator())))
   {
      bool contentChanged = false;

      list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(listUri));
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipDialogMonitor::publishContent listUri %s list %p",
                    listUri->data(), list);

      // Search for the contact in this list
      resource = list->getResource(contact);
      if (resource)
      {
         resource->getInstance(id, state);

         // :TODO:
         // The following code is incorrect.  The "state" of a resource in a
         // resource list reports on the status of the subscription
         // from the resource list server to the resource's event
         // publisher (draft-ietf-simple-event-list-07, top of p. 10),
         // not the on-hook/off-hook status of a SIP agent for an AOR.

         if (dialogEvent->isEmpty())
         {
            resource->setInstance(id, STATE_TERMINATED);
         }
         else
         {
            resource->setInstance(id, STATE_ACTIVE);
         }

         list->buildBody();
         contentChanged = true;
      }

      if (contentChanged)
      {
         // Publish the content to the subscribe server
         // Make a copy, because mpSipPublishContentMgr will own it.
         HttpBody* pHttpBody = new HttpBody(*(HttpBody*)list);
	 mSipPublishContentMgr.publish(listUri->data(),
                                       DIALOG_EVENT_TYPE,
                                       DIALOG_EVENT_TYPE,
                                       1,
                                       &pHttpBody);
      }
   }
}
bool SipDialogMonitor::removeExtension(UtlString& groupName, Url& contactUrl)
{
   bool result = false;
   mLock.acquire();
   // Check whether the group has existed or not. If not, return false.
   SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName));
   if (list == NULL)
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::removeExtension group %s does not exist",
                    groupName.data());   
   }
   else
   {
      // Check whether the contact has existed or not
      UtlString resourceId;
      contactUrl.getIdentity(resourceId);
      Resource* resource = list->getResource(resourceId);
      if (resource)
      {
         UtlString* dialogHandle = dynamic_cast <UtlString *> (mDialogHandleList.findValue(&resourceId));
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipDialogMonitor::removeExtension Calling endSubscription(%s)",
                       dialogHandle->data());
         UtlBoolean status = mpSipSubscribeClient->endSubscription(dialogHandle->data());
                  
         if (!status)
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipDialogMonitor::removeExtension Unsubscription failed for %s.",
                          resourceId.data());
         }

         mDialogHandleList.destroy(&resourceId);
         resource = list->removeResource(resource);
         delete resource;
         
         result = true;
      }
      else
      {
         OsSysLog::add(FAC_LOG, PRI_WARNING,
                       "SipDialogMonitor::removeExtension subscription for contact %s does not exists.",
                       resourceId.data());
      }
   }

   mLock.release();   
   return result;   
}
bool SipPresenceMonitor::addExtension(UtlString& groupName, Url& contactUrl)
{
   bool result = false;
   mLock.acquire();

   // Check whether the group has already existed. If not, create one.
   SipResourceList* list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName));
   if (list == NULL)
   {
      UtlString* listName = new UtlString(groupName);
      list = new SipResourceList((UtlBoolean)TRUE, listName->data(), PRESENCE_EVENT_TYPE);

      mMonitoredLists.insertKeyAndValue(listName, list);
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::addExtension insert listName %s and object %p to the resource list",
                    groupName.data(), list);
   }

   // Check whether the contact has already been added to the group
   UtlString resourceId;
   contactUrl.getIdentity(resourceId);
   Resource* resource = list->getResource(resourceId);
   if (resource == NULL)
   {
      resource = new Resource(resourceId);

      UtlString userName;
      contactUrl.getDisplayName(userName);
      resource->setName(userName);

      UtlString id;
      makeId(id, resourceId);
      resource->setInstance(id, STATE_PENDING);
      list->insertResource(resource);

      result = true;
   }
   else
   {
      OsSysLog::add(FAC_LOG, PRI_WARNING,
                    "SipPresenceMonitor::addExtension contact %s already exists.",
                    resourceId.data());
   }

   int dummy;
   list->buildBody(&dummy);

   mLock.release();
   return result;
}
bool SipDialogMonitor::removeExtension(UtlString& groupName, Url& contactUrl)
{
   bool result = false;
   mLock.acquire();
   // Check whether the group exists or not. If not, return false.
   SipResourceList* list =
      dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName));
   if (list == NULL)
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipDialogMonitor::removeExtension group %s does not exist",
                    groupName.data());   
   }
   else
   {
      // Check whether the contact exists in the group or not.
      UtlString resourceId;
      contactUrl.getIdentity(resourceId);
      Resource* resource = list->getResource(resourceId);
      if (resource)
      {
         // If it exists, get the early dialog handle for the SUBSCRIBE,
         // which specifies all of its subscriptions.
         UtlString* earlyDialogHandle =
            dynamic_cast <UtlString *> (mDialogHandleList.findValue(&resourceId));
         if (earlyDialogHandle)
         {
            OsSysLog::add(FAC_SIP, PRI_DEBUG,
                          "SipDialogMonitor::removeExtension Calling endSubscription(%s)",
                          earlyDialogHandle->data());
            // Terminate the subscription.
            UtlBoolean status = mpSipSubscribeClient->endSubscription(earlyDialogHandle->data());
                     
            if (!status)
            {
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "SipDialogMonitor::removeExtension Unsubscription failed for %s.",
                             resourceId.data());
            }

            // Remove the remembered state for dialog event notices.
            destroyDialogState(earlyDialogHandle);
         }
         else
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipDialogMonitor::removeExtension no dialogHandle for %s.",
                          resourceId.data());
         }
         
         // Now delete all the references to this URI.
         mDialogHandleList.destroy(&resourceId);
         resource = list->removeResource(resource);
         delete resource;
         
         result = true;
      }
      else
      {
         OsSysLog::add(FAC_LOG, PRI_WARNING,
                       "SipDialogMonitor::removeExtension subscription for contact %s does not exists.",
                       resourceId.data());
      }
   }

   mLock.release();   
   return result;   
}
bool SipDialogMonitor::addExtension(UtlString& groupName, Url& contactUrl)
{
   bool result = false;
   mLock.acquire();
   
   // Check whether the group already exists. If not, create one.
   SipResourceList* list =
      dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(&groupName));
   if (list == NULL)
   {
      UtlString* listName = new UtlString(groupName);
      list = new SipResourceList((UtlBoolean)TRUE, listName->data(),
                                 DIALOG_EVENT_TYPE);
      
      mMonitoredLists.insertKeyAndValue(listName, list);
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipDialogMonitor::addExtension insert listName %s and object %p to the resource list",
                    groupName.data(), list);   
   }

   // Check whether the contact has already been added to the group.
   UtlString resourceId;
   contactUrl.getIdentity(resourceId);
   Resource* resource = list->getResource(resourceId);
   if (resource == NULL)
   {
      // If not, add it.
      resource = new Resource(resourceId);
      
      UtlString userName;
      contactUrl.getDisplayName(userName);
      resource->setName(userName);
      
      UtlString id;
      NetMd5Codec::encode(resourceId, id);
      resource->setInstance(id, STATE_PENDING);
      list->insertResource(resource);
      
      // Set up the subscription to the URI.
      OsSysLog::add(FAC_LOG, PRI_DEBUG,
                    "SipDialogMonitor::addExtension Sending out the SUBSCRIBE to contact %s",
                    resourceId.data());

      UtlString toUrl;
      contactUrl.toString(toUrl);
      
      UtlString fromUri = "dialogMonitor@" + mDomainName;
      UtlString earlyDialogHandle;
            
      UtlBoolean status = mpSipSubscribeClient->addSubscription(resourceId.data(),
                                                                DIALOG_EVENT_TYPE,
                                                                DIALOG_EVENT_CONTENT_TYPE,
                                                                fromUri.data(),
                                                                toUrl.data(),
                                                                mContact.data(),
                                                                mRefreshTimeout,
                                                                (void *) this,
                                                                SipDialogMonitor::subscriptionStateCallback,
                                                                SipDialogMonitor::notifyEventCallback,
                                                                earlyDialogHandle);
               
      if (!status)
      {
         result = false;
         OsSysLog::add(FAC_LOG, PRI_ERR,
                       "SipDialogMonitor::addExtension Subscription failed to contact %s.",
                       resourceId.data());
      }
      else
      {
         mDialogHandleList.insertKeyAndValue(new UtlString(resourceId),
                                             new UtlString(earlyDialogHandle));
         createDialogState(&earlyDialogHandle);
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipDialogMonitor::addExtension Added earlyDialogHandle: %s",
                       earlyDialogHandle.data());
         result = true;
      }
   }
   else
   {
      OsSysLog::add(FAC_LOG, PRI_WARNING,
                    "SipDialogMonitor::addExtension contact %s already exists.",
                    resourceId.data());
   }

   int dummy;
   list->buildBody(dummy);
   
   mLock.release();
   return result;
}
void SipDialogMonitor::publishContent(UtlString& contact, SipDialogEvent* dialogEvent)
{
   bool contentChanged;
   
   // Loop through all the resource lists
   UtlHashMapIterator iterator(mMonitoredLists);
   UtlString* listUri;
   SipResourceList* list;
   Resource* resource;
   UtlString id, state;
   while (listUri = dynamic_cast <UtlString *> (iterator()))
   {
      contentChanged = false;
      
      list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(listUri));
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogMonitor::publishContent listUri %s list %p",
                    listUri->data(), list); 

      // Search for the contact in this list
      resource = list->getResource(contact);
      if (resource)
      {
         resource->getInstance(id, state);
         
         if (dialogEvent->isEmpty())
         {
            resource->setInstance(id, STATE_TERMINATED);
         }
         else
         {
            Dialog* dialog = dialogEvent->getFirstDialog();
            
            UtlString state, event, code;
            dialog->getState(state, event, code);
            
            if (state.compareTo(STATE_TERMINATED) == 0)
            {
               resource->setInstance(id, STATE_TERMINATED);
            }
            else
            {     
               resource->setInstance(id, STATE_ACTIVE);
            }
         }
         
         list->buildBody();
         contentChanged = true;
      }
      
      if (contentChanged)
      {
         int numOldContents;
         HttpBody* oldContent[1];           
   
         // Publish the content to the subscribe server
         if (!mSipPublishContentMgr.publish(listUri->data(), DIALOG_EVENT_TYPE, DIALOG_EVENT_TYPE, 1, (HttpBody**)&list, 1, numOldContents, oldContent))
         {
            UtlString dialogContent;
            int length;
            
            list->getBytes(&dialogContent, &length);
            OsSysLog::add(FAC_SIP, PRI_ERR, "SipDialogMonitor::publishContent DialogEvent %s\n was not successfully published to the subscribe server",
                          dialogContent.data());
         }
      }
   }
}
void SipPresenceMonitor::publishContent(UtlString& contact, SipPresenceEvent* presenceEvent)
{
#ifdef SUPPORT_RESOURCE_LIST
   // Loop through all the resource lists
   UtlHashMapIterator iterator(mMonitoredLists);
   UtlString* listUri;
   SipResourceList* list;
   Resource* resource;
   UtlString id, state;
   while (listUri = dynamic_cast <UtlString *> (iterator()))
   {
      bool contentChanged = false;

      list = dynamic_cast <SipResourceList *> (mMonitoredLists.findValue(listUri));
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::publishContent listUri %s list %p",
                    listUri->data(), list);

      // Search for the contact in this list
      resource = list->getResource(contact);
      if (resource)
      {
         resource->getInstance(id, state);

         if (presenceEvent->isEmpty())
         {
            resource->setInstance(id, STATE_TERMINATED);
         }
         else
         {
            UtlString id;
            makeId(id, contact);
            Tuple* tuple = presenceEvent->getTuple(id);

            UtlString status;
            tuple->getStatus(status);

            if (status.compareTo(STATUS_CLOSED) == 0)
            {
               resource->setInstance(id, STATE_TERMINATED);
            }
            else
            {
               resource->setInstance(id, STATE_ACTIVE);
            }
         }

         list->buildBody();
         contentChanged = true;
      }

      if (contentChanged)
      {
         // Publish the content to the subscribe server
         // Make a copy, because mpSipPublishContentMgr will own it.
         HttpBody* pHttpBody = new HttpBody(*(HttpBody*)list);
         mSipPublishContentMgr.publish(listUri->data(),
                                       PRESENCE_EVENT_TYPE, PRESENCE_EVENT_TYPE,
                                       1, &pHttpBody);
      }
   }
#endif

   // Publish the content to the subscribe server
   // Make a copy, because mpSipPublishContentMgr will own it.
   HttpBody* pHttpBody = new HttpBody(*(HttpBody*)presenceEvent);
   mSipPublishContentMgr.publish(contact.data(),
                                 PRESENCE_EVENT_TYPE, PRESENCE_EVENT_TYPE,
                                 1, &pHttpBody);
}