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; }
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(); }
// 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"); }
// 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; }