bool SipXMessageObserver::handleIncomingInfoStatus(SipMessage* pSipMessage)
{
    if (NULL == pSipMessage)
    {
        // something went wrong
        return false;
    }

    SIPX_INFO hInfo = (SIPX_INFO)pSipMessage->getResponseListenerData();
    if (hInfo)
    {
        SIPX_INFOSTATUS_INFO infoStatus;

        memset((void*) &infoStatus, 0, sizeof(SIPX_INFOSTATUS_INFO));

        infoStatus.hInfo = hInfo;
        SIPX_INFO_DATA* pInfoData = sipxInfoLookup(hInfo, SIPX_LOCK_READ);
        infoStatus.nSize = sizeof(SIPX_INFOSTATUS_INFO);
        infoStatus.responseCode = pSipMessage->getResponseStatusCode();
        infoStatus.event = INFOSTATUS_RESPONSE;

        int statusCode = pSipMessage->getResponseStatusCode();
        if (statusCode < 400)
        {
        infoStatus.status = SIPX_MESSAGE_OK;
        }
        else if (statusCode < 500)
        {
            infoStatus.status = SIPX_MESSAGE_FAILURE;
        }
        else if (statusCode < 600)
        {
            infoStatus.status = SIPX_MESSAGE_SERVER_FAILURE;
        }
        else
        {
            infoStatus.status = SIPX_MESSAGE_GLOBAL_FAILURE;
        }

        UtlString sResponseText;
        pSipMessage->getResponseStatusText(&sResponseText);
        infoStatus.szResponseText = sResponseText.data();

        UtlVoidPtr* ptr = NULL;
        UtlSListIterator eventListenerItor(*g_pEventListeners);
        while ((ptr = (UtlVoidPtr*) eventListenerItor()) != NULL)
        {
            EVENT_LISTENER_DATA *pData = (EVENT_LISTENER_DATA*) ptr->getValue();
            if (pInfoData->pInst == pData->pInst)
            {
                pData->pCallbackProc(EVENT_CATEGORY_INFO_STATUS, &infoStatus, pData->pUserData);
            }
        }

        pInfoData->pInst->pSipUserAgent->removeMessageObserver(*(this->getMessageQueue()), (void*)hInfo);

        // release lock
        sipxInfoReleaseLock(pInfoData, SIPX_LOCK_READ);
        // info message has been handled, so go ahead and delete the object
        sipxInfoObjectFree(hInfo);
     }
     return true;
}
bool SipXMessageObserver::handleIncomingInfoStatus(SipMessage* pSipMessage, int messageType)
{
    OsStackTraceLogger stackLogger(FAC_SIPXTAPI, PRI_DEBUG, "SipXMessageObserver::handleIncomingInfoStatus");

    if (NULL == pSipMessage)
    {
        // something went wrong
        return false;
    }
    
    SIPX_INFO hInfo = (SIPX_INFO)pSipMessage->getResponseListenerData();
    if (hInfo)
    {
        SIPX_INFOSTATUS_INFO infoStatus;
        
        memset((void*) &infoStatus, 0, sizeof(SIPX_INFOSTATUS_INFO));
        infoStatus.nSize = sizeof(SIPX_INFOSTATUS_INFO);
        infoStatus.responseCode = pSipMessage->getResponseStatusCode();
        infoStatus.event = INFOSTATUS_RESPONSE;
        
        infoStatus.hInfo = hInfo;
        SIPX_INFO_DATA* pInfoData = sipxInfoLookup(hInfo, SIPX_LOCK_READ, stackLogger);

        if(pInfoData)
        {
            
            int statusCode = pSipMessage->getResponseStatusCode();
            if (statusCode < 400)
            {
                infoStatus.status = SIPX_MESSAGE_OK;
            }
            // May want to add special case for authentication
            //else if(statusCode == HTTP_PROXY_UNAUTHORIZED_CODE || statusCode == HTTP_UNAUTHORIZED_CODE)
            //{
            //    infoStatus.status = 
            //}
            else if (statusCode < 500)
            {
                infoStatus.status = SIPX_MESSAGE_FAILURE;
            }
            else if (statusCode < 600)
            {
                infoStatus.status = SIPX_MESSAGE_SERVER_FAILURE;
            }
            else 
            {
                infoStatus.status = SIPX_MESSAGE_GLOBAL_FAILURE;
            }
            
            UtlString sResponseText;
            pSipMessage->getResponseStatusText(&sResponseText);
            infoStatus.szResponseText = sResponseText.data();
            
            UtlVoidPtr* ptr = NULL;
            OsLock eventLock(*g_pEventListenerLock) ;
            UtlSListIterator eventListenerItor(*g_pEventListeners);
            while ((ptr = (UtlVoidPtr*) eventListenerItor()) != NULL)
            {
                EVENT_LISTENER_DATA *pData = (EVENT_LISTENER_DATA*) ptr->getValue();
                if (pData)
                {
                    if(pInfoData->pInst == pData->pInst)
                    {
                        pData->pCallbackProc(EVENT_CATEGORY_INFO_STATUS, &infoStatus, pData->pUserData);
                    }
                }
                else
                {
                    OsSysLog::add(FAC_SIPXTAPI, PRI_ERR,
                            "SipXMessageObserver::handleIncomingInfoStatus NULL pData  in listener");
                }
            }

            // I think the following is incorrect.  I think this is not added as a global mssage observer, only
            // as an obsever to individual transactions when the INFO is sent.  So this is not needed.
            pInfoData->pInst->pSipUserAgent->removeMessageObserver(*(this->getMessageQueue()), (void*)hInfo);
            
            // release lock
            sipxInfoReleaseLock(pInfoData, SIPX_LOCK_READ, stackLogger);
        }

        // If an INFO was resent with auth credentials, don't remove the INFO object.  Wait
        // for the response to the resend.
        if(messageType != SipMessageEvent::AUTHENTICATION_RETRY)
        {
            // info message has been handled, so go ahead and delete the object    
            sipxInfoObjectFree(hInfo);
        }
     }
     return true;
}