bool SipPresenceMonitor::addPresenceEvent(UtlString& contact, SipPresenceEvent* presenceEvent)
{
   bool requiredPublish = false;
   
   if (mPresenceEventList.find(&contact) == NULL)
   {
      requiredPublish = true;
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::addPresenceEvent adding the presenceEvent %p for contact %s",
                    presenceEvent, contact.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::addPresenceEvent presenceEvent %p for contact %s already exists, just update the content.",
                    presenceEvent, contact.data());
                    
      // Get the object from the presence event list
      UtlContainable* oldKey;
      UtlContainable* foundValue;
      foundValue = mPresenceEventList.findValue(&contact);
      SipPresenceEvent* oldPresenceEvent = dynamic_cast <SipPresenceEvent *> (foundValue);
      UtlString oldStatus, status;
      UtlString id;
      NetMd5Codec::encode(contact, id);
      oldPresenceEvent->getTuple(id)->getStatus(oldStatus);
      presenceEvent->getTuple(id)->getStatus(status);
      
      if (status.compareTo(oldStatus) != 0)
      {
         requiredPublish = true;
         oldKey = mPresenceEventList.removeKeyAndValue(&contact, foundValue);
         delete oldKey;

         OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipPresenceMonitor::addPresenceEvent remove the presenceEvent %p for contact %s",
                       oldPresenceEvent, contact.data()); 

         if (oldPresenceEvent)
         {
            delete oldPresenceEvent;
         }
      }
   }

   if (requiredPublish)
   {         
      // Insert it into the presence event list
      presenceEvent->buildBody();
      mPresenceEventList.insertKeyAndValue(new UtlString(contact), presenceEvent);

      if (mToBePublished)
      { 
         // Publish the content to the resource list
         publishContent(contact, presenceEvent);
      }
      
      // Notify the state change
      notifyStateChange(contact, presenceEvent);
   }
   
   return requiredPublish;
}
Example #2
0
void SipPresenceMonitor::getState(const Url& aor, UtlString& status)
{
   UtlString contact;
   aor.getUserId(contact);
   contact += mHostAndPort;
   // Make the contact be a proper URI by prepending "sip:".
   contact.prepend("sip:");

   UtlContainable* foundValue;

   mLock.acquire();

   foundValue = mPresenceEventList.findValue(&contact);

   if (foundValue)
   {
      SipPresenceEvent* presenceEvent = dynamic_cast <SipPresenceEvent *> (foundValue);
      UtlString id;
      makeId(id, contact);
      presenceEvent->getTuple(id)->getStatus(status);
      OsSysLog::add(FAC_SIP, PRI_ERR, "SipPresenceMonitor::getState contact %s state = %s",
                    contact.data(), status.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_ERR, "SipPresenceMonitor::getState contact %s does not exist",
                    contact.data());

      status = STATUS_CLOSED;
   }

   mLock.release();
}
Example #3
0
// Write the presence events to the persistent file.
void SipPresenceMonitor::writePersistentFile()
{
   mLock.acquire();

   // Create an empty document
   TiXmlDocument document;

   // Create a hard coded standalone declaration section
   document.Parse("<?xml version=\"1.0\" standalone=\"yes\"?>");

   // Create the root node container
   TiXmlElement itemsElement ("items");
   itemsElement.SetAttribute("type", sType.data());
   itemsElement.SetAttribute("xmlns", sXmlNamespace.data());

   int timeNow = (int)OsDateTime::getSecsSinceEpoch();
   itemsElement.SetAttribute("timestamp", timeNow);

   // mPresenceEventList is a hash map that maps contacts to SipPresenceEvents.
   // SipPresenceEvents are hash maps of contacts to Tuples.  In practice,
   // a SipPresenceEvent has only one Tuple.  (And if it had more, there
   // would be no way to discover what they are, as there is no iterator.)
   // Tuples are triples:  id, contact, status.

   // Loop through all the events in mPresenceEventList.
   UtlHashMapIterator iterator(mPresenceEventList);
   UtlString* contact;
   while ((contact = dynamic_cast <UtlString*> (iterator())))
   {
      // Create an item container
      TiXmlElement itemElement ("item");

      // Get the SipPresenceEvent.
      SipPresenceEvent* event =
         dynamic_cast <SipPresenceEvent*> (iterator.value());

      // Calculate the id of the Tuple.
      UtlString id;
      makeId(id, *contact);

      // Get the Tuple.
      Tuple* tuple = event->getTuple(id);

      // Get the status.
      UtlString status;
      tuple->getStatus(status);

      // Construct the <item>.
      TiXmlElement id_element("id");
      TiXmlText id_content(id);
      id_element.InsertEndChild(id_content);
      itemElement.InsertEndChild(id_element);
      TiXmlElement contact_element("contact");
      TiXmlText contact_content(contact->data());
      contact_element.InsertEndChild(contact_content);
      itemElement.InsertEndChild(contact_element);
      TiXmlElement status_element("status");
      TiXmlText status_content(status);
      status_element.InsertEndChild(status_content);
      itemElement.InsertEndChild(status_element);

      // Add the <item> element to the <items> element.
      itemsElement.InsertEndChild ( itemElement );
   }

   // Attach <items> to the root node to the document
   document.InsertEndChild(itemsElement);
   document.SaveFile(mPersistentFile);

   mLock.release();

   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPresenceMonitorPersistenceTask::writePersistentFile file written");
}
Example #4
0
// Returns TRUE if the requested state is different from the current state.
bool SipPresenceMonitor::addPresenceEvent(UtlString& contact, SipPresenceEvent* presenceEvent)
{
   mLock.acquire();

   bool requiredPublish = false;

   if (mPresenceEventList.find(&contact) == NULL)
   {
      requiredPublish = true;
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipPresenceMonitor::addPresenceEvent adding presenceEvent %p for contact %s",
                    presenceEvent, contact.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipPresenceMonitor::addPresenceEvent presenceEvent %p for contact %s already exists, updating its contents.",
                    presenceEvent, contact.data());

      // Get the object from the presence event list
      UtlContainable* oldKey;
      UtlContainable* foundValue;
      foundValue = mPresenceEventList.findValue(&contact);
      SipPresenceEvent* oldPresenceEvent = dynamic_cast <SipPresenceEvent *> (foundValue);
      UtlString oldStatus, status;
      UtlString id;
      makeId(id, contact);
      oldPresenceEvent->getTuple(id)->getStatus(oldStatus);
      presenceEvent->getTuple(id)->getStatus(status);

      if (status.compareTo(oldStatus) != 0)
      {
         requiredPublish = true;

         // Since we will be saving a new value, remove the old one.
         oldKey = mPresenceEventList.removeKeyAndValue(&contact, foundValue);
         delete oldKey;
         if (oldPresenceEvent)
         {
            delete oldPresenceEvent;
         }
      }
   }

   if (requiredPublish)
   {
      // Insert it into the presence event list.
      presenceEvent->buildBody();
      mPresenceEventList.insertKeyAndValue(new UtlString(contact), presenceEvent);
      if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG))
      {
         UtlString b;
         ssize_t l;
         presenceEvent->getBytes(&b, &l);

         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipPresenceMonitor::addPresenceEvent presenceEvent %p for contact '%s' body '%s' is different from previous presenceEvent",
                       presenceEvent, contact.data(), b.data());
      }

      if (mToBePublished)
      {
         // Publish the content to the resource list.
         publishContent(contact, presenceEvent);
      }

      // Notify the state change.
      notifyStateChange(contact, presenceEvent);

      if (!mPersistentFile.isNull())
      {
         // Start the save timer.
         mPersistenceTimer.oneshotAfter(sPersistInterval);
      }
   }
   else
   {
      // Since this presenceEvent will not be published (it does not
      // change the state we've sent out), delete it now.
      delete presenceEvent;
   }

   mLock.release();
   return requiredPublish;
}