Example #1
0
// Generate the default content for presence status.
void PresenceDefaultConstructor::generateDefaultContent(SipPublishContentMgr* contentMgr,
							const char* resourceId,
							const char* eventTypeKey,
							const char* eventType)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "PresenceDefaultConstructor::generateDefaultContent "
                 "generating default content for resourceId '%s', "
                 "eventTypeKey '%s', eventType '%s'",
                 resourceId, eventTypeKey, eventType);

   // Create a presence event package and store it in the publisher.
   // This code parallels SipPresenceMonitor::setStatus.
   SipPresenceEvent* sipPresenceEvent = new SipPresenceEvent(resourceId);

   UtlString id;
   UtlString resource(resourceId);
   SipPresenceMonitor::makeId(id, resource);
   Tuple* tuple = new Tuple(id.data());
   tuple->setStatus(DEFAULT_PRESENCE_STATUS);
   tuple->setContact(resourceId, 1.0);

   sipPresenceEvent->insertTuple(tuple);

   // Build its text version.
   sipPresenceEvent->buildBody();

   // Publish the event (storing it for the resource), but set
   // noNotify to TRUE, because our caller will push the NOTIFYs.
   contentMgr->publish(resourceId, eventTypeKey, eventType, 1,
                       &(HttpBody*&) sipPresenceEvent, TRUE);
}
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 #3
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 #4
0
// Returns TRUE if the requested state is different from the current state.
bool SipPresenceMonitor::setStatus(const Url& aor, const Status value)
{
   if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG))
   {
      UtlString aorString;
      aor.toString(aorString);
      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipPresenceMonitor::setStatus aor = '%s', value = %d %s",
                    aorString.data(), value,
                    (value == StateChangeNotifier::PRESENT ? "PRESENT" :
                     value == StateChangeNotifier::AWAY ? "AWAY" :
                     "UNKNOWN"));
   }

   bool result = false;

   UtlString contact;
   aor.getUserId(contact);
   contact += mHostAndPort;
   // Make the contact be a proper URI by prepending "sip:".
   contact.prepend("sip:");

   // Create a presence event package and store it in the publisher
   SipPresenceEvent* sipPresenceEvent = new SipPresenceEvent(contact);

   UtlString id;
   makeId(id, contact);

   Tuple* tuple = new Tuple(id.data());

   tuple->setStatus(value == StateChangeNotifier::PRESENT ?
                    STATUS_OPEN :
                    STATUS_CLOSED);
   tuple->setContact(contact, 1.0);

   sipPresenceEvent->insertTuple(tuple);

   // Add the SipPresenceEvent object to the presence event list.
   result = addPresenceEvent(contact, sipPresenceEvent);

   return result;
}
bool SipPresenceMonitor::setStatus(const Url& aor, const Status value)
{
   bool result = false;
   
   UtlString contact;
   aor.getIdentity(contact);
   
   // Create a presence event package and store it in the publisher
   SipPresenceEvent* sipPresenceEvent = new SipPresenceEvent(contact);
      
   UtlString id;
   NetMd5Codec::encode(contact, id);
   
   Tuple* tuple = new Tuple(id.data());
   
   if (value == StateChangeNotifier::PRESENT)
   {
      tuple->setStatus(STATUS_OPEN);
      tuple->setContact(contact, 1.0);
   }
   else
   {
      if (value == StateChangeNotifier::AWAY)
      {
         tuple->setStatus(STATUS_CLOSE);
         tuple->setContact(contact, 1.0);
      }
   }

   sipPresenceEvent->insertTuple(tuple); 
   
   // Add the SipPresenceEvent object to the subscribe list
   result = addPresenceEvent(contact, sipPresenceEvent);
   
   return result;
} 
Example #6
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 #7
0
// Read the presence events from the persistent file.
void SipPresenceMonitor::readPersistentFile()
{
   mLock.acquire();

   // Initialize Tiny XML document object.
   TiXmlDocument document;
   TiXmlNode* items_node;
   if (
      // Load the XML into it.
      document.LoadFile(mPersistentFile.data()) &&
      // Find the top element, which should be an <items>.
      (items_node = document.FirstChild("items")) != NULL &&
      items_node->Type() == TiXmlNode::ELEMENT)
   {
      // Find all the <item> elements.
      int item_seq_no = 0;
      for (TiXmlNode* item_node = 0;
           (item_node = items_node->IterateChildren("item",
                                                    item_node));
         )
      {
         if (item_node->Type() == TiXmlNode::ELEMENT)
         {
            item_seq_no++;
            TiXmlElement* item_element = item_node->ToElement();

            // Process the <item> element.
            bool item_valid = true;

            // Process the 'id' child.
            UtlString id;
            TiXmlNode* id_node = item_element->FirstChild("id");
            if (id_node && id_node->Type() == TiXmlNode::ELEMENT)
            {
               textContentShallow(id, id_node);
               if (id.isNull())
               {
                  // Id null.
                  OsSysLog::add(FAC_ACD, PRI_ERR,
                                "id child of <item> was null");
                  item_valid = false;
               }
            }
            else
            {
               // Id missing.
               OsSysLog::add(FAC_ACD, PRI_ERR,
                             "id child of <item> was missing");
               item_valid = false;
            }

            // Process the 'contact' child.
            UtlString contact;
            TiXmlNode* contact_node = item_element->FirstChild("contact");
            if (contact_node && contact_node->Type() == TiXmlNode::ELEMENT)
            {
               textContentShallow(contact, contact_node);
               if (contact.isNull())
               {
                  // Contact null.
                  OsSysLog::add(FAC_ACD, PRI_ERR,
                                "contact child of <item> was null");
                  item_valid = false;
               }
            }
            else
            {
               // Contact missing.
               OsSysLog::add(FAC_ACD, PRI_ERR,
                             "contact child of <item> was missing");
               item_valid = false;
            }

            // Process the 'status' child.
            UtlString status;
            TiXmlNode* status_node = item_element->FirstChild("status");
            if (status_node && status_node->Type() == TiXmlNode::ELEMENT)
            {
               textContentShallow(status, status_node);
               if (status.isNull())
               {
                  // Status null.
                  OsSysLog::add(FAC_ACD, PRI_ERR,
                                "status child of <item> was null");
                  item_valid = false;
               }
            }
            else
            {
               // Status missing.
               OsSysLog::add(FAC_ACD, PRI_ERR,
                             "status child of <item> was missing");
               item_valid = false;
            }

            OsSysLog::add(FAC_ACD, PRI_DEBUG,
                          "SipPresenceMonitor::readPersistentFile row: id = '%s', contact = '%s', status = '%s'",
                          id.data(), contact.data(), status.data());

            if (item_valid)
            {
               // Create a presence event package and store it in
               // mPresenceEventList.
               SipPresenceEvent* sipPresenceEvent = new SipPresenceEvent(contact);
               Tuple* tuple = new Tuple(id.data());
               tuple->setStatus(status);
               tuple->setContact(contact, 1.0);
               sipPresenceEvent->insertTuple(tuple);
               sipPresenceEvent->buildBody();
               mPresenceEventList.insertKeyAndValue(new UtlString(contact),
                                                    sipPresenceEvent);
            }
            else
            {
            OsSysLog::add(FAC_ACD, PRI_ERR,
                          "In presence status file '%s', <item> number %d had invalid or incomplete information.  The readable information was: id = '%s', contact = '%s', status = '%s'",
                          mPersistentFile.data(), item_seq_no,
                          id.data(), contact.data(), status.data());

            }
         }
      }
   }
   else
   {
      // Report error parsing file.
      OsSysLog::add(FAC_ACD, PRI_CRIT,
                    "Presence status file '%s' could not be parsed.",
                    mPersistentFile.data());
   }

   mLock.release();

   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPresenceMonitorPersistenceTask::readPersistentFile done");
}
Example #8
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;
}