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 AutoAnswerCallbackProc(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 == OFFERING_ACTIVE) { 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); } sipxCallAnswer(hCall); printf("Call with ID %d has been answered.\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; }
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; }
// Called when the callAnswerTimer fires. OsStatus CallAnswerNotification::signal(int eventData) { return sipxCallAnswer(mHCall) == SIPX_RESULT_SUCCESS ? OS_SUCCESS : OS_FAILED; }
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; }