bool basicCall_CallBack_Receive_Reject(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; SIPX_LINE hLine = pCallInfo->hLine; SIPX_CALL hCall = pCallInfo->hCall; g_recorder2.addEvent(hLine, pCallInfo->event, pCallInfo->cause) ; switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallReject(hCall) ; sipxCallDestroy(hCall) ; break ; case CALLSTATE_ALERTING: break ; case CALLSTATE_DISCONNECTED: break ; default: break ; } } return true; }
bool SIPX_CALLING_CONVENTION AutoRejectCallback(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; g_hAutoRejectCallbackCall = pCallInfo->hCall; g_hAutoRejectCallbackLine = pCallInfo->hLine; // If we have user data verify the line url against it if (pUserData) { char szBuffer[500] ; size_t nBuffer ; if (strlen((const char*) pUserData)) { if (g_hAutoRejectCallbackLine) // hLine can be 0, and therefore, sipxLineGetURI should fail) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(g_hAutoRejectCallbackLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; } } } switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallReject(g_hAutoRejectCallbackCall) ; break ; case CALLSTATE_DISCONNECTED: { SIPX_CALL hDestroy = g_hAutoRejectCallbackCall ; sipxCallDestroy(hDestroy) ; } break ; default: break ; } } return true; }
bool SIPX_CALLING_CONVENTION basicCall_CallBack_Receive3_busy(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; SIPX_LINE hLine = pCallInfo->hLine; SIPX_CALL hCall = pCallInfo->hCall; g_recorder3.addEvent(hLine, pCallInfo->event, pCallInfo->cause) ; // If we have user data verify the line url against it if (pUserData) { char szBuffer[500] ; size_t nBuffer ; if (strlen((const char*) pUserData)) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(hLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; // printf("comparing %s to %s\n", pUserData, szBuffer) ; CPPUNIT_ASSERT(strcmp((char*) pUserData, szBuffer) == 0) ; } else { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(hLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_FAILURE) ; } } switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallReject(hCall) ; sipxCallDestroy(hCall) ; break ; default: break ; } } return true; }
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; }
bool ACDCallManager::eventCallback(SIPX_EVENT_CATEGORY category, void *pInfo) { ACDLine* pLineRef; if (pInfo == NULL) return false; mLock.acquire(); SIPX_CALLSTATE_INFO* pCallInfo = static_cast<SIPX_CALLSTATE_INFO*>(pInfo); char sEvent[128] ; sipxEventToString(category, pInfo, sEvent, sizeof(sEvent)) ; OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::eventCallback - SIPXTAPI event hCall=%d %s", pCallInfo->hCall, sEvent) ; if (category == EVENT_CATEGORY_CALLSTATE) { switch (pCallInfo->event) { case CALLSTATE_OFFERING: osPrintf("OFFERING(%d) - Line: %d, Call: %d\n", pCallInfo->cause, pCallInfo->hLine, pCallInfo->hCall); // An incoming call is being offered. First validate // that it is not a call that has been transferred to the ACD line if (TRUE == validateTransferToLine(pCallInfo)) { OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::eventCallback - CALLSTATE_OFFERING::%d to the ACD Line REJECTED", pCallInfo->cause); sipxCallReject(pCallInfo->hCall, SIP_BAD_REQUEST_CODE, "ACD Transfer Offer Rejected"); } else { // Validate the line that it is arriving on. pLineRef = mpAcdLineManager->getAcdLineReference(pCallInfo->hLine); if (pLineRef == NULL) { // Call arrived on an invalid line. Reject it! sipxCallReject(pCallInfo->hCall, SIP_NOT_FOUND_CODE, "Invalid ACD Line Offered"); osPrintf("OFFERING REJECTED - Line: %d, Call: %d\n", pCallInfo->hLine, pCallInfo->hCall); OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::eventCallback" " - CALLSTATE_OFFERING::%d on LINE:%d INVALID LINE REJECTED", pCallInfo->cause, pCallInfo->hLine); } else { // The line is valid. Now see if the line will accept the call. if (pLineRef->isLineBusy()) { // The line is busy. Reject it! sipxCallReject(pCallInfo->hCall, SIP_BUSY_CODE, "ACD Line Busy"); osPrintf("OFFERING REJECTED - Line: %d, Call: %d\n", pCallInfo->hLine, pCallInfo->hCall); OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::eventCallback - CALLSTATE_OFFERING::%d on LINE:%d BUSY", pCallInfo->cause, pCallInfo->hLine); } else { // Before we accept the call, check whether we exceed the max number of calls allowed if (mCallHandleMap.entries() < mpAcdServer->getMaxCallAllowed()) { // Also check if there is any agent signed in ! UtlString mQueueUriString = pLineRef->getAcdQueue(); ACDQueue* pDestinationQueue = pLineRef->getAcdLineManager()->getAcdQueueManager()->getAcdQueueReference(mQueueUriString); if ((pDestinationQueue != NULL) && ( pDestinationQueue->checkAgentAvailable() || pDestinationQueue->checkOverflowEntryAvailable())) { // Accept the call! sipxCallAccept(pCallInfo->hCall); osPrintf("OFFERING ACCEPTED - Line: %d, Call: %d\n", pCallInfo->hLine, pCallInfo->hCall); OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::eventCallback - CALLSTATE_OFFERING::%d on LINE:%d ACCEPTED", pCallInfo->cause, pCallInfo->hLine); } else { // No signed in agent reject the call sipxCallReject(pCallInfo->hCall, SIP_TEMPORARILY_UNAVAILABLE_CODE, "ACD No Agent"); OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::eventCallback - CALLSTATE_OFFERING::reject the call %d due to no signed in agent", pCallInfo->hCall); } } else { // We exceed the max allowed, reject the call sipxCallReject(pCallInfo->hCall, SIP_TEMPORARILY_UNAVAILABLE_CODE, "ACD Maximum Calls Exceeded"); OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::eventCallback - CALLSTATE_OFFERING::reject the call %d due to exceed the max calls allowed (%zu)", pCallInfo->hCall, mCallHandleMap.entries()); } } } } break; case CALLSTATE_ALERTING: osPrintf("ALERTING(%d) - Line: %d, Call: %d\n", pCallInfo->cause, pCallInfo->hLine, pCallInfo->hCall); // Validate the incoming line pLineRef = mpAcdLineManager->getAcdLineReference(pCallInfo->hLine); if (pLineRef == NULL) { // Call arrived on an invalid line. Reject it! sipxCallReject(pCallInfo->hCall, SIP_NOT_FOUND_CODE, "Invalid ACD Line Alerting"); OsSysLog::add(FAC_ACD, PRI_WARNING, "ACDCallManager::eventCallback - CALLSTATE_ALERTING::%d on LINE:%d INVALID LINE", pCallInfo->cause, pCallInfo->hLine); } else { // Now create an ACDCall object to handle it. if (createACDCall(pLineRef, pCallInfo->hCall) != OS_SUCCESS) { // The line rejected the call, drop it! sipxCallReject(pCallInfo->hCall, SIP_BAD_REQUEST_CODE, "ACD Line Reject"); osPrintf("ALERTING REJECTED - Line: %d, Call: %d\n", pCallInfo->hLine, pCallInfo->hCall); } else { // Success updateCallState(pCallInfo); } } break; case CALLSTATE_CONNECTED: osPrintf("CONNECTED(%d) - Line: %d, Call: %d\n", pCallInfo->cause, pCallInfo->hLine, pCallInfo->hCall); updateCallState(pCallInfo); break; case CALLSTATE_DISCONNECTED: osPrintf("DISCONNECTED(%d) - Line: %d, Call: %d\n", pCallInfo->cause, pCallInfo->hLine, pCallInfo->hCall); if (updateCallState(pCallInfo) == OS_FAILED) { // If no one handled it, make sure to destroy the call // otherwise there is a handle leak. SIPX_CALL tmpCall = pCallInfo->hCall ; sipxCallDestroy(tmpCall) ; } break; case CALLSTATE_DESTROYED: osPrintf("DESTROYED(%d) - Line: %d, Call: %d\n", pCallInfo->cause, pCallInfo->hLine, pCallInfo->hCall); updateCallState(pCallInfo); break; case CALLSTATE_NEWCALL: OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::eventCallback - " "CALLSTATE_NEWCALL::cause %d, hCallHandle %d hAssociateCallHandle %d remAddr %s", pCallInfo->cause, pCallInfo->hCall, pCallInfo->hAssociatedCall, pCallInfo->remoteAddress); if (pCallInfo->cause == CALLSTATE_NEW_CALL_TRANSFER) updateTransferCallState(pCallInfo); break; case CALLSTATE_REMOTE_OFFERING: OsSysLog::add(FAC_ACD, gACD_DEBUG, "ACDCallManager::eventCallback - " "CALLSTATE_REMOTE_OFFERING::cause %d, hCallHandle %d hAssociateCallHandle %d remAddr %s", pCallInfo->cause, pCallInfo->hCall, pCallInfo->hAssociatedCall, pCallInfo->remoteAddress); if (pCallInfo->cause == CALLSTATE_REMOTE_OFFERING_NORMAL) updateTransferCallState(pCallInfo); break ; case CALLSTATE_TRANSFER: updateCallState(pCallInfo); break; case CALLSTATE_DIALTONE: case CALLSTATE_REMOTE_ALERTING: case CALLSTATE_AUDIO_EVENT: case CALLSTATE_SECURITY_EVENT: case CALLSTATE_UNKNOWN: break; } } mLock.release(); return true; }
PhoneState* PhoneState::OnOffer(SIPX_CALL hCall) { sipxCallReject(hCall); // default behavior is to just reject the call return this; }