bool ACDCallManager::validateTransferToLine(SIPX_CALLSTATE_INFO* pCallInfo) { SIPX_CALL hAssociatedCallHandle; int callEvent; int callCause; const char* remUri; char userUri[512]; mLock.acquire(); // Extract the call handle and state info hAssociatedCallHandle = pCallInfo->hAssociatedCall; callEvent = pCallInfo->event; callCause = pCallInfo->cause; remUri = pCallInfo->remoteAddress; UtlString userId, hostAddress; Url remoteUrl(remUri); remoteUrl.getUserId(userId); remoteUrl.getHostAddress(hostAddress); if (remUri) { // Now find out if there is an agent for this remUri sprintf(userUri,"sip:%s@%s",userId.data(),hostAddress.data()); UtlString agentUri(userUri); ACDAgent* pAgentRef = mpAcdServer->getAcdAgentManager()->getAcdAgentReference(agentUri); if ((pAgentRef) && (FALSE == pAgentRef->isFree())) { mLock.release(); return TRUE; } } mLock.release(); return FALSE; }
void ACDCallManager::updateTransferCallState(SIPX_CALLSTATE_INFO* pCallInfo) { SIPX_CALL hCallHandle = SIPX_CALL_NULL; SIPX_CALL hAssociatedCallHandle; int callEvent; int callCause; const char* remUri; char userUri[512]; ACDCall* pCallRef; mLock.acquire(); // Extract the call handle and state info hAssociatedCallHandle = pCallInfo->hAssociatedCall; callEvent = pCallInfo->event; callCause = pCallInfo->cause; remUri = pCallInfo->remoteAddress; /** * For the NEWCALL_TRANSFER event - find the ACDCall object instance * on the basis of the Associated call handle (from the older leg). */ if (pCallInfo->cause == CALLSTATE_NEW_CALL_TRANSFER) { if (TRUE == validateTransferToLine(pCallInfo)) { // Don't allow agents to transfer calls INTO the acd. It screws // things up. The correct behavior would be to move the call // the agent is currently handling into a new queue, but due to // the inability to remove calls from a conference, this just doesn't // work. Hangup on the transfer attempt. Ths should leave // caller and agent connected. OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::updateTransferCallState - " "CALLSTATE_OFFERING::%d to the ACD Line REJECTED", pCallInfo->cause); sipxCallReject(pCallInfo->hCall, SIP_BAD_REQUEST_CODE, "Agent Transfer Loop Rejected"); return ; } // not an agent transferring into the acd hCallHandle = hAssociatedCallHandle; UtlInt callKey(hCallHandle); pCallRef = dynamic_cast<ACDCall*>(mAgentCallHandleMap.findValue(&callKey)); } else // not new call transfer { UtlInt searchKey(pCallInfo->hCall); pCallRef = dynamic_cast<ACDCall*>(mTransferCallHandleMap.findValue(&searchKey)); } if (pCallRef != NULL) { if (callCause == CALLSTATE_NEW_CALL_TRANSFER) { addMapTransferAgentCallHandleToCall(pCallInfo->hCall, pCallRef); pCallRef->mFlagTransfer = TRUE; // only set TRUE here. } if ( (callCause == CALLSTATE_REMOTE_OFFERING_NORMAL) && (pCallRef->mFlagTransfer == TRUE)) { UtlString userId, hostAddress; Url remoteUrl(remUri); remoteUrl.getUserId(userId); remoteUrl.getHostAddress(hostAddress); if (remUri) { // Now find the agent for this remUri sprintf(userUri,"sip:%s@%s",userId.data(),hostAddress.data()); UtlString agentUri(userUri); ACDAgent* pAgentRef = mpAcdServer->getAcdAgentManager()->getAcdAgentReference(agentUri); if (!pAgentRef) { OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::updateTransferCallState - " "Failed to find Agent. This is probably an agent that is not signed in: " "call(%d), TransferAgentCall(%d), agentUri(%s)", pCallRef->getCallHandle(), pCallInfo->hCall, agentUri.data()); // A non registered agent is not yet supported - so do not try ! pAgentRef = mpAcdServer->getAcdAgentManager()->createACDAgent(userUri, "dummy", "", FALSE, FALSE, NULL, TRUE); if (!pAgentRef) { assert(0); } } //set the mhCallHandle of the Agent object pAgentRef->setCallHandle(pCallInfo->hCall); // set the transfer agent object in the call object pCallRef->mpTransferAgent = pAgentRef; OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::updateTransferCallState - " "success in finding Agent: call(%d), TransferAgentCall(%d) AgentUri(%s)", pCallRef->getCallHandle(), pCallInfo->hCall, pAgentRef->getUriString()->data()); } } if ( (callCause == CALLSTATE_REMOTE_OFFERING_NORMAL) && (pCallRef->mFlagTransfer == FALSE)) { ; // do nothing } else { pCallRef->updateState(hCallHandle, callEvent, callCause); } } mLock.release(); return; }