예제 #1
0
    /** Test the setValue() method. 
    *
    *   The test data for this method is
    *      a) For a NULL  pointer set a different type
    *      a) Set the value from one Non-NULL to another Non-NULL
    *      d) set the value from Non-NULL to NULL 
    */
    void testSetValue() 
    {
        const char* prefix ; 
        const char* suffix1 = " : test return value" ; 
        const char* suffix2 = " : test that value has been set" ; 
        string Message ; 

        UtlVoidPtr testVoidObj ; 
        void* returnValue ; 
        void* newValue  ;
        void* oldValue = 0 ; 
 
        newValue = (void*)"Hello world" ; 
        returnValue = testVoidObj.setValue(newValue) ; 
        prefix = "For a VoidPtr object which is not NULL, test setValue(void* value) " \
            "where val is non NULL " ; 
        TestUtilities::createMessage(2, &Message, prefix, suffix1) ; 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)oldValue, (void*)returnValue) ; 
        TestUtilities::createMessage(2, &Message, prefix, suffix2) ; 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)newValue, \
            (void*)testVoidObj.getValue()) ; 

        oldValue = testVoidObj.getValue() ; 
        prefix = "Test setValue(void* value) where value is not NULL and the " \
           "existing object is not NULL" ; 
        newValue = (void*)"Hello again world" ; 
        returnValue = (void*)testVoidObj.setValue(newValue) ; 
        TestUtilities::createMessage(2, &Message, prefix, suffix1) ;
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)oldValue, (void*)returnValue) ;  
        TestUtilities::createMessage(2, &Message, prefix, suffix2) ; 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)newValue, \
            (void*)testVoidObj.getValue()) ; 

        oldValue = testVoidObj.getValue() ; 
        prefix = "Test setValue(void* value) where value = NULL and existing object is not" ; 
        newValue = 0 ; 
        returnValue = (void*)testVoidObj.setValue(newValue) ; 
        TestUtilities::createMessage(2, &Message, prefix, suffix1) ; 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)oldValue, (void*)returnValue); 
        TestUtilities::createMessage(2, &Message, prefix, suffix1) ; 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(Message.data(), (void*)newValue, \
            (void*)testVoidObj.getValue()) ; 

    } //testSetValue
예제 #2
0
// Process a notify event callback.
void ResourceInstance::notifyEventCallback(const UtlString* dialogHandle,
                                           const UtlString* content)
{
   OsSysLog::add(FAC_RLS, PRI_DEBUG,
                 "ResourceInstance::notifyEventCallback mInstanceName = '%s', content = '%s'",
                 mInstanceName.data(), content->data());
   // Set to true if we find publishable data.
   bool publish = false;

   // Set the subscription state to "active".
   mSubscriptionState = "active";

   // Save the content as text for the RFC 4662 resource list events.
   mContent.remove(0);
   mContent.append(*content);
   mContentPresent = TRUE;

   // Dissect the XML for each dialog event and store it in a map
   // so we can construct BroadWorks-style resource list events
   // (which have to have full state).

   // Initialize Tiny XML document object.
   TiXmlDocument xmlDialogEvent;
   TiXmlNode* dialog_info_node;
   if (
       // Load the XML into it.
       xmlDialogEvent.Parse(mContent.data()) &&
       // Find the top element, which should be a <dialog-info>.
       (dialog_info_node = xmlDialogEvent.FirstChild("dialog-info")) != NULL &&
       dialog_info_node->Type() == TiXmlNode::ELEMENT)
   {
      // Check the state attribute.
      const char* p = dialog_info_node->ToElement()->Attribute("state");
      if (p && strcmp(p, "full") == 0)
      {
         // If the state is "full", terminate all non-terminated dialogs.  (XECS-1668)
         terminateXmlDialogs();
         publish = true;
         OsSysLog::add(FAC_RLS, PRI_DEBUG,
                       "ResourceInstance::notifyEventCallback all non-terminated dialogs");
      }

      // Find all the <dialog> elements.
      for (TiXmlNode* dialog_node = 0;
           (dialog_node = dialog_info_node->IterateChildren("dialog",
                                                            dialog_node));
         )
      {
         if (dialog_node->Type() == TiXmlNode::ELEMENT)
         {
            TiXmlElement* dialog_element = dialog_node->ToElement();

            // Determine if the <dialog> is a bogus report of a NAT Keepalive
            // OPTIONS message, as reported by Polycom SPIP firmware 3.1.2.
            // (XTRN-425)  If so, ignore it.

#ifdef NAT_KEEPALIVE_DETECT
            const char* call_id_attr = dialog_element->Attribute("call-id");
            // Reject <dialog>s on the narrowest grounds, that is, only if the
            // call-id attribute is present and contains NAT_KEEPALIVE_SIGNATURE.
            const bool ok =
               !(call_id_attr &&
                 strstr(call_id_attr,
                        NAT_KEEPALIVE_SIGNATURE) != NULL);
#else
            const bool ok = true;
#endif
            if (ok)
            {
               // Now that we've got a <dialog> element, edit it to fit
               // into a consolidated event notice.
               publish = true;

               // Prepend the resource instance name to the 'id'
               // attribute, so it is unique within the <resource>.
               UtlString id(mInstanceName);
               // mInstanceName is guaranteed to not contain ';', because
               // it is a dialog handle that we generate by concatenating
               // the Call-Id and tags using ',' as a separator.  And ';'
               // may not appear in Call-Ids or tags.
               id.append(";");
               id.append(dialog_element->Attribute("id"));
               dialog_element->SetAttribute("id", id.data());

               // Prepare the display name, so we can insert it easily
               // when we generate consolidated events.
               // Find or add the <local> element.
               TiXmlNode* local = dialog_element->FirstChild("local");
               if (!local)
               {
                  local = dialog_element->LinkEndChild(new TiXmlElement("local"));
               }
               // Find or add the <local><identity> element.
               TiXmlNode* identity = local->FirstChild("identity");
               if (!identity)
               {
                  identity =
                     local->LinkEndChild(new TiXmlElement("identity"));
               }
               // Clear the display attribute.
               identity->ToElement()->SetAttribute("display", "");

               // Put the resource URI as the content of the
               // <local><identity> element.
               // First, remove all text children.
               TiXmlNode* child;
               for (TiXmlNode* prev_child = 0;
                    (child = identity->IterateChildren(prev_child));
                  )
               {
                  if (child->Type() == TiXmlNode::TEXT)
                  {
                     identity->RemoveChild(child);
                     // Leave prev_child unchanged.
                  }
                  else
                  {
                     prev_child = child;
                  }
               }
               // Insert a text child containing the URI.
               identity->LinkEndChild(new TiXmlText(getResourceCached()->
                                                    getUri()->data()));

               // Now that we have the XML all nice and pretty, store a copy of
               // it in mXmlDialogs.
               // Clone the XML and create a UtlVoidPtr to wrap it.
               TiXmlElement* alloc_xml = dialog_element->Clone()->ToElement();

               // Look for an earlier version of this dialog in the hash map.
               UtlVoidPtr* p = dynamic_cast <UtlVoidPtr*> (mXmlDialogs.findValue(&id));
               if (p)
               {
                  // Replace the old XML with new XML.
                  delete static_cast <TiXmlElement*> (p->getValue());
                  p->setValue(alloc_xml);
                  OsSysLog::add(FAC_RLS, PRI_DEBUG,
                                "ResourceInstance::notifyEventCallback replaced dialog with id '%s'",
                                id.data());
               }
               else
               {
                  // Check that we don't have too many dialogs.
                  if (mXmlDialogs.entries() <
                      getResourceListServer()->getMaxDialogsInResInst())
                  {
                     mXmlDialogs.insertKeyAndValue(new UtlString(id),
                                                   new UtlVoidPtr(alloc_xml));
                     OsSysLog::add(FAC_RLS, PRI_DEBUG,
                                   "ResourceInstance::notifyEventCallback added dialog with id '%s'",
                                   id.data());
                  }
                  else
                  {
                     // Free alloc_xml, because we aren't saving a pointer to it.
                     delete alloc_xml;
                     OsSysLog::add(FAC_RLS, PRI_ERR,
                                   "ResourceInstance::notifyEventCallback cannot add dialog with id '%s', already %zu in ResourceInstance '%s'",                                id.data(), mXmlDialogs.entries(),
                                   mInstanceName.data());
                  }
               }
            }
            else
            {
               // The <dialog> was rejected because it appears to report
               // a NAT Maintainer OPTIONS message.
               // We log this at DEBUG level because if these appear,
               // there is likely to be one every 20 seconds.
               OsSysLog::add(FAC_RLS, PRI_DEBUG,
                             "ResourceInstance::notifyEventCallback "
                             "ignored <dialog> reporting a NAT Keepalive message "
                             "in subscription dialog handle '%s' - "
                             "see XTRN-426",
                             mInstanceName.data());
            }
         }
      }
   }
   else
   {
      // Report error parsing XML.
      OsSysLog::add(FAC_RLS, PRI_ERR,
                    "ResourceInstance::notifyEventCallback "
                    "Dialog event from '%s' not parsable.",
                    getResourceCached()->getUri()->data());
      OsSysLog::add(FAC_RLS, PRI_INFO,
                    "ResourceInstance::notifyEventCallback "
                    "Dialog event content is '%s'",
                    content->data());
      // Throw away the content, since we cannot generate matching
      // consolidated content.
      mContentPresent = FALSE;
      mContent.remove(0);
      destroyXmlDialogs();
   }

   // Get the change published, if we found <dialog> that was not incorrect.
   if (publish)
   {
      getResourceCached()->setToBePublished(FALSE, getResourceCached()->getUri());
   }
}