bool basicCall_CallBack_Receive_Hangup(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: sipxCallAccept(hCall) ; break ; case CALLSTATE_ALERTING: sipxCallAnswer(hCall) ; OsTask::delay(CALL_DELAY); sipxCallDestroy(hCall) ; break ; case CALLSTATE_DISCONNECTED: break ; default: break ; } } return true; }
void AutoAcceptCallbackProc(SIPX_CALL hCall, SIPX_LINE hLine, SIPX_CALLSTATE_MAJOR eMajor, SIPX_CALLSTATE_MINOR eMinor, void* pUser) { char szBuffer[128] ; char* szEventDesc = sipxCallEventToString(eMajor, eMinor, szBuffer, sizeof(szBuffer)) ; if(eMinor == NEW_CALL_NORMAL) { if(sipxCallAccept(hCall) == SIPX_RESULT_SUCCESS) { printf("Call with ID %d has been accepted.\n", hCall); } else { printf("Call with ID %d failed to be accepted.\n", hCall); } } else if(eMinor == DISCONNECTED_NORMAL) { sipxCallDestroy(hCall); } }
bool AutoAnswerCallback_Secure(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; if (g_hAutoAnswerCallbackCall == 0) { g_hAutoAnswerCallbackCall = pCallInfo->hCall; } else if (g_hAutoAnswerCallbackCall != pCallInfo->hCall) { g_hAutoAnswerCallbackCallOther = pCallInfo->hCall ; } g_hAutoAnswerCallbackLine = 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 (pCallInfo->hLine) // hLine can be 0, and therefore, sipxLineGetURI should fail) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(pCallInfo->hLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; } } } switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallAccept(pCallInfo->hCall, NULL, gpAcceptSecurity) ; break ; case CALLSTATE_ALERTING: { int delay = rand() % 40 ; OsTask::delay(delay) ; sipxCallAnswer(pCallInfo->hCall) ; } break ; case CALLSTATE_DISCONNECTED: { SIPX_CALL hDestroy = pCallInfo->hCall ; sipxCallDestroy(hDestroy) ; } break ; default: break ; } } return true; }
bool SIPX_CALLING_CONVENTION basicCall_CallBack_Receive(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) ; // 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 (hLine) // hLine can be 0, and therefore, sipxLineGetURI should fail) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(hLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; // an event can come in with what appears to be the "wrong" user data. // for instance, if a listener is removed and a new listener is added immediately with new user data. // 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: sipxCallAccept(hCall) ; break ; case CALLSTATE_ALERTING: sipxCallAnswer(hCall) ; break ; case CALLSTATE_DISCONNECTED: sipxCallDestroy(hCall) ; break ; default: break ; } } return true; }
bool SIPX_CALLING_CONVENTION basicCall_CallBack_Receive3_hangup(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: sipxCallAccept(hCall) ; break ; case CALLSTATE_ALERTING: sipxCallAnswer(hCall) ; break ; case CALLSTATE_CONNECTED: ghCallHangup = hCall; break ; case CALLSTATE_DISCONNECTED: break ; default: break ; } } return true; }
bool SIPX_CALLING_CONVENTION AutoAnswerHangupCallback(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; g_hAutoAnswerHangupCallbackCall = pCallInfo->hCall; g_hAutoAnswerHangupCallbackLine = 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_hAutoAnswerHangupCallbackLine) // hLine can be 0, and therefore, sipxLineGetURI should fail) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(g_hAutoAnswerHangupCallbackLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; } } } switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallAccept(g_hAutoAnswerHangupCallbackCall) ; break ; case CALLSTATE_ALERTING: { sipxCallAnswer(g_hAutoAnswerHangupCallbackCall) ; OsTask::delay(CALL_DELAY); SIPX_CALL hDestroy = g_hAutoAnswerHangupCallbackCall ; sipxCallDestroy(hDestroy) ; } break ; default: break ; } } return true; }
int CallAcceptCommand::execute(int argc, char* argv[]) { int commandStatus = CommandProcessor::COMMAND_FAILED; if(argc == 2) { if(sipxCallAccept(atoi(argv[1])) == SIPX_RESULT_SUCCESS) { printf("Call with ID %d has been accepted.\n", atoi(argv[1])); } else { printf("Call with ID %d failed to be accepted.\n", atoi(argv[1])); } } else { UtlString usage; getUsage(argv[0], &usage); printf("%s", usage.data()); commandStatus = CommandProcessor::COMMAND_BAD_SYNTAX; } return commandStatus; }
bool EventCallBack(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { assert (pInfo != NULL); // Dump event char cBuf[1024] ; sipxEventToString(category, pInfo, cBuf, sizeof(cBuf)); printf("%s\n", cBuf) ; if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = static_cast<SIPX_CALLSTATE_INFO*>(pInfo); printf(" hCall=%d, hAssociatedCall=%d\n", pCallInfo->hCall, pCallInfo->hAssociatedCall) ; SIPX_CALL hTmpCall = pCallInfo->hCall; switch (pCallInfo->event) { case CALLSTATE_OFFERING: #if defined(_WIN32) && defined(VIDEO) gDisplay.type = SIPX_WINDOW_HANDLE_TYPE; gDisplay.handle = ghVideo; if (bVideo) { sipxCallAccept(pCallInfo->hCall, &gDisplay) ; } else #endif { sipxCallAccept(pCallInfo->hCall); } break ; case CALLSTATE_ALERTING: sipxCallAnswer(pCallInfo->hCall) ; break ; case CALLSTATE_CONNECTED: SLEEP(1000) ; // BAD: Do not block the callback thread // Play file if provided if (g_szFile) { if (!playFile(g_szFile, pCallInfo->hCall)) { printf("Failed to play file: %s\n", g_szFile) ; } } // Play tones if provided if (g_szPlayTones) { if (!playTones(g_szPlayTones, pCallInfo->hCall)) { printf("Failed to play tones: %s\n", g_szPlayTones) ; } } break ; case CALLSTATE_DISCONNECTED: sipxCallDestroy(&hTmpCall) ; break ; // ::TODO:: Fix me with new media event // case CALLSTATE_AUDIO_EVENT: // if (pCallInfo->cause == CALLSTATE_CAUSE_AUDIO_START) // { // printf("* Negotiated codec: %s, payload type %d\n", pCallInfo->codecs.audioCodec.cName, pCallInfo->codecs.audioCodec.iPayloadType); // } // break; case CALLSTATE_DESTROYED: break ; } } return true; }
bool EventCallBack(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { assert (pInfo != NULL); // Dump event char cBuf[1024] ; // Print the timestamp if requested. if (g_timestamp) { OsDateTime d; OsDateTime::getCurTime(d); UtlString s; d.getIsoTimeStringZ(s); printf("%s ", s.data()); } printf("%s\n", sipxEventToString(category, pInfo, cBuf, sizeof(cBuf))) ; if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = static_cast<SIPX_CALLSTATE_INFO*>(pInfo); printf(" hCall=%d, hAssociatedCall=%d\n", pCallInfo->hCall, pCallInfo->hAssociatedCall) ; switch (pCallInfo->event) { case CALLSTATE_OFFERING: // Get and print the From: URI. { char remote[200]; sipxCallGetRemoteID(pCallInfo->hCall, remote, sizeof (remote)); printf(" From: %s\n", remote); } sipxCallAccept(pCallInfo->hCall) ; break ; case CALLSTATE_ALERTING: clearLoopback() ; { // Determine the answering delay. int delay; if (g_callAnswerDelay == NULL || g_callAnswerDelay[0] == '\0') { // No answer string is active, so delay is 0. delay = 0; } else { // Get the delay to be used from the delay string. delay = atoi(g_callAnswerDelay); // Remove the first number, if there is a comma. char* p = strchr(g_callAnswerDelay, ','); if (p != NULL) { g_callAnswerDelay = p + 1; } } if (delay == 0) { // If the delay is 0, answer immediately. sipxCallAnswer(pCallInfo->hCall); } else { // The delay is non-0, so set the timer to answer. // Stop the timer in case it is running. callAnswerTimer.stop(); // Record the call to be answered. callAnswerNotification.setHCall(pCallInfo->hCall); // Construct the delay to be used. OsTime d(delay, 0); // Start the timer. callAnswerTimer.oneshotAfter(d); } } break ; case CALLSTATE_CONNECTED: // Per conversation with Bob A., commented this sleep out // to prevent trouble with processing re-INVITEs that come // just after INVITEs. This should be replaced with a proper // timer-wait event. But that leads to the open question // of whether to use the sipX OsTimer system, or the underlying // OS mechanisms (to avoid dependency on sipXportLib). Ugh. //SLEEP(1000) ; // BAD: Do not block the callback thread // Start the timer that limits the length of the call. { // Stop the timer in case it is running. callHangupTimer.stop(); // Record the call to be answered. callHangupNotification.setHCall(pCallInfo->hCall); // Start the timer, scaled to seconds. OsTime delay(iDuration, 0); callHangupTimer.oneshotAfter(delay); } // Play file if provided if (g_szFile) { if (!playFile(g_szFile, pCallInfo->hCall)) { printf("Failed to play file: %s\n", g_szFile) ; } } // Play tones if provided if (g_szPlayTones) { if (!playTones(g_szPlayTones, pCallInfo->hCall)) { printf("Failed to play tones: %s\n", g_szPlayTones) ; } } break ; case CALLSTATE_DISCONNECTED: // Stop the timers in case they are running. callAnswerTimer.stop(); callHangupTimer.stop(); // Destroy the call. sipxCallDestroy(pCallInfo->hCall) ; break ; case CALLSTATE_AUDIO_EVENT: if (pCallInfo->cause == CALLSTATE_AUDIO_START) { printf("* Negotiated codec: %s, payload type %d\n", pCallInfo->codecs.audioCodec.cName, pCallInfo->codecs.audioCodec.iPayloadType); } break; case CALLSTATE_DESTROYED: // Stop the timer in case it is running. callAnswerTimer.stop(); break ; default: // There are many other events which we ignore. break; } } // Ensure the output is not delayed by buffering. fflush(stdout); return true; }
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; }
bool SIPX_CALLING_CONVENTION AutoAnswerCallbackHolder(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = (SIPX_CALLSTATE_INFO*) pInfo; if (g_hAutoAnswerCallbackCallHolder == 0) { g_hAutoAnswerCallbackCallHolder = pCallInfo->hCall; } else if (g_hAutoAnswerCallbackCallHolder != pCallInfo->hCall) { g_hAutoAnswerCallbackCallOtherHolder = pCallInfo->hCall ; } g_hAutoAnswerCallbackLineHolder = 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 (pCallInfo->hLine) // hLine can be 0, and therefore, sipxLineGetURI should fail) { CPPUNIT_ASSERT_EQUAL(sipxLineGetURI(pCallInfo->hLine, szBuffer, sizeof(szBuffer), nBuffer), SIPX_RESULT_SUCCESS) ; } } } switch(pCallInfo->event) { case CALLSTATE_OFFERING: sipxCallAccept(pCallInfo->hCall) ; break ; case CALLSTATE_ALERTING: { // printf("%d Alerting\n", GetTickCount()) ; int delay = rand() % 500 ; OsTask::delay(delay) ; // printf("%d Answering\n", GetTickCount()) ; sipxCallAnswer(pCallInfo->hCall) ; delay = rand() % 500 ; OsTask::delay(delay) ; // printf("%d Holding\n", GetTickCount()) ; sipxCallHold(pCallInfo->hCall, true) ; } break ; case CALLSTATE_DISCONNECTED: { // printf("%d Dropping\n", GetTickCount()) ; SIPX_CALL hDestroy = pCallInfo->hCall ; sipxCallDestroy(hDestroy) ; } break ; default: break ; } } return true; }
bool EventCallBack(SIPX_EVENT_CATEGORY category, void* pInfo, void* pUserData) { assert (pInfo != NULL); // Dump event char cBuf[1024] ; printf("%s\n", sipxEventToString(category, pInfo, cBuf, sizeof(cBuf))) ; if (category == EVENT_CATEGORY_CALLSTATE) { SIPX_CALLSTATE_INFO* pCallInfo = static_cast<SIPX_CALLSTATE_INFO*>(pInfo); printf(" hCall=%d, hAssociatedCall=%d\n", pCallInfo->hCall, pCallInfo->hAssociatedCall) ; switch (pCallInfo->event) { case CALLSTATE_OFFERING: #if defined(_WIN32) && defined(VIDEO) gDisplay.type = SIPX_WINDOW_HANDLE_TYPE; gDisplay.handle = ghVideo; if (bVideo) { sipxCallAccept(pCallInfo->hCall, &gDisplay) ; } else #endif { sipxCallAccept(pCallInfo->hCall); } break ; case CALLSTATE_ALERTING: clearLoopback() ; sipxCallAnswer(pCallInfo->hCall) ; break ; case CALLSTATE_CONNECTED: SLEEP(1000) ; // BAD: Do not block the callback thread // Play file if provided if (g_szFile) { if (!playFile(g_szFile, pCallInfo->hCall)) { printf("Failed to play file: %s\n", g_szFile) ; } } // Play tones if provided if (g_szPlayTones) { if (!playTones(g_szPlayTones, pCallInfo->hCall)) { printf("Failed to play tones: %s\n", g_szPlayTones) ; } } break ; case CALLSTATE_DISCONNECTED: sipxCallDestroy(pCallInfo->hCall) ; break ; case CALLSTATE_DESTROYED: if (gbOneCallMode) { gbShutdown = true; } break ; } } else if (category == EVENT_CATEGORY_MEDIA) { SIPX_MEDIA_INFO* pMediaInfo = static_cast<SIPX_MEDIA_INFO*>(pInfo); switch(pMediaInfo->event) { case MEDIA_LOCAL_START: printf("* Negotiated codec: %s, payload type %d\n", pMediaInfo->codec.audioCodec.cName, pMediaInfo->codec.audioCodec.iPayloadType); break; } } return true; }