bool SipXMessageObserver::handleIncomingInfoMessage(SipMessage* pMessage) { bool bRet = false; SIPX_INSTANCE_DATA* pInst = (SIPX_INSTANCE_DATA*) pMessage->getResponseListenerData(); if (NULL != pInst && NULL != pMessage) { if (mTestResponseCode != 0) // for unit testing purposes. { if (mTestResponseCode == 408) // a timeout response is being tested { // simulate a timeout .... OsTask::delay(1000); // respond to whomever sent us the message SipMessage sipResponse; sipResponse.setOkResponseData(pMessage); sipResponse.setResponseFirstHeaderLine(SIP_PROTOCOL_VERSION, mTestResponseCode, "timed out"); pInst->pSipUserAgent->send(sipResponse); return true ; } } else { // respond to whomever sent us the message SipMessage sipResponse; sipResponse.setOkResponseData(pMessage); pInst->pSipUserAgent->send(sipResponse); } // Find Line UtlString lineId; pMessage->getToUri(&lineId); UtlString requestUri; pMessage->getRequestUri(&requestUri); SIPX_LINE hLine = sipxLineLookupHandle(pInst, lineId.data(), requestUri); if (!pMessage->isResponse()) { // find call UtlString callId; pMessage->getCallIdField(&callId); SIPX_CALL hCall = sipxCallLookupHandle(callId, pInst->pCallManager); if (0 == hCall) { // we are unaware of the call context } SIPX_INFO_DATA* pInfoData = new SIPX_INFO_DATA; memset((void*)pInfoData, 0, sizeof(SIPX_INFO_DATA)); pInfoData->infoData.nSize = sizeof(SIPX_INFO_INFO); pInfoData->infoData.hCall = hCall; pInfoData->infoData.hLine = hLine; Url fromUrl; pInfoData->infoData.szFromURL = lineId.data(); pInfoData->infoData.nContentLength = pMessage->getContentLength(); // get and set the content type UtlString contentType; pMessage->getContentType(&contentType) ; pInfoData->infoData.szContentType = strdup(contentType.data()); // get the user agent UtlString userAgent; pMessage->getUserAgentField(&userAgent); pInfoData->infoData.szUserAgent = strdup(userAgent.data()); // get the content UtlString body; ssize_t dummyLength = pMessage->getContentLength(); const HttpBody* pBody = pMessage->getBody(); if (pBody == NULL) { return false; } pBody->getBytes(&body, &dummyLength); pInfoData->infoData.pContent = body.data(); // set the Instance pInfoData->pInst = pInst; // Create Mutex pInfoData->pMutex = new OsRWMutex(OsRWMutex::Q_FIFO); UtlVoidPtr* ptr = NULL; UtlSListIterator eventListenerItor(*g_pEventListeners); while ((ptr = (UtlVoidPtr*) eventListenerItor()) != NULL) { EVENT_LISTENER_DATA *pData = (EVENT_LISTENER_DATA*) ptr->getValue(); if (pData->pInst == pInfoData->pInst) { pData->pCallbackProc(EVENT_CATEGORY_INFO, &(pInfoData->infoData), pData->pUserData); } } bRet = true; } // if (0 != hLine) } // if (NULL != pInst && NULL != pMessage) return bRet; }
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; }