SIP Call Flow Samples

CREATING A BASIC SIP APPLICATION


Developing a SIP application is quite easy with Creacode SIP Application Server. State of art call processor allows perfect synchronization between SIP call signals and scripting language. CCS scripting language is more systematic and meaningful than treditional XML based call flow generators. So developers could create powerful and flexible SIP applications in a very short time.

Following example demonstrates the relation between SIP application scripts and related SIP signalling cases. Please click SIP signals to see the related application code.

Summary of this scenario is below:

1. Caller and Callee registers Creacode SAS.

2. Caller initiates a call which is accepted by Creacode SAS registrar.

3. Creacode SAS plays "welcome" and "language selection" announcements to the caller.

4. Creacode SAS sends authentication request to a billing server(radius or web server) and plays remaining credit caller according to authentication response.

5. Sends authorization request to billing server for the called number and gets maximum call duration for this session.

6. Creacode SAS starts a new call towards destination after performing routeplan and dialplan rules. When the call is established between calling and called party, Creacode SAS starts a session timer to countdown from maximum call duration.

7. Creacode SAS interrupts the call and plays last minute announcement to caller and connects caller to callee again.

8. Creacode SAS ends the call session in case of :

- Maximum call duration expires. Sends SIP BYE message to caller and callee and ends this session.

- If caller or callee hangs up the phone. Sends SIP BYE message to the talking part and ends this call session.

                          
	      CALLER                CREACODE SAS                CALLEE
		|                        |                        |
		|                        |                        |
		|>REGISTER ------------->|<------------- REGISTER<|
		|                        |                        |
		|<--------------- 200 Ok<|>200 Ok---------------->|
		|                        |                        |
		|>INVITE (sdp)---------->|                        |
		|                        |                        |
		|<----------- 100 TRYING<|                        |
		|                        |                        |
		|<-----------180 RINGING<|                        |
		|                        |                        |
		|<----------(sdp) 200 Ok<|                        |
		|                        |                        |
		|>ACK------------------->|                        |
		|                        |                        |
		|<=====MEDIA SESSION====>|                        |
		|                        |                        |
		|                        |>INVITE (sdp)---------->|
		|                        |                        |
		|                        |<---------- 180 RINGING<|
		|                        |                        |
		|                        |<----------(sdp) 200 Ok<|
		|                        |                        |
		|                        |>ACK ------------------>|
		|                        |                        |
		|<-------(sdp) re-INVITE<|                        |
		|                        |                        |
		|>200 Ok (sdp)---------->|                        |
		|                        |                        |
		|<------------------ ACK<|                        |
		|                        |                        |
		|<================MEDIA SESSION==================>|
		|                        |                        |
		|                        |>re-INVITE (sdp)------->|
		|                        |                        |
		|                        |<----------(sdp) 200 Ok<|
		|                        |                        |
		|                        |>ACK ------------------>|
		|                        |                        |
		|<-------(sdp) re-INVITE<|                        |
		|                        |                        |
		|>200 Ok (sdp)---------->|                        |
		|                        |                        |
		|<------------------ ACK<|                        |
		|                        |                        |
		|                        |                        |
		|<===LAST MIN WARNING===>|                        |
		|                        |                        |	
		|                        |                        |
		|<-------(sdp) re-INVITE<|                        |
		|                        |                        |
		|>200 Ok (sdp)---------->|                        |
		|                        |                        |
		|<------------------ ACK<|                        |
		|                        |                        |
		|                        |>re-INVITE (sdp)------->|
		|                        |                        |
		|                        |<----------(sdp) 200 Ok<|
		|                        |                        |
		|                        |>ACK ------------------>|
		|                        |                        |
		|<================MEDIA SESSION==================>|
		|                        |                        |
		|>BYE ------------------>|                        |
		|                        |                        |
		|<--------------- 20O Ok<|                        |
		|                        |                        |
		|                        |>BYE ------------------>|
		|                        |                        |
		|                        |<--------------- 200 Ok<| 
		|                        |                        |
		
			
             
Main.ccs
// Global variables
string APP_SERVER_RADIUS = "192.168.1.3";
string APP_SERVER_HTTP = "127.0.0.1";
bool g_CallEstablished = FALSE;
string g_strDigits;
string g_strUser;
string g_strPassword;
string g_strh323confid;
string g_strSetupTime;
int iTimerID;
g_CreditAmountInt;
g_CreditAmountDec;
g_nMaxCallDuration;

// main function
FUNCTION main()
{
	// generate 32 char random string
	// Exp: output  70562F75F241E8A46B07CDD8417F8EF2 
	g_strh323confid = randHex(32);
	LOG("Conf Id : " + g_strh323confid);
	
	// Switch to next script file named NewSession.ccs in Prepaid directory
	RunScript("Prepaid\\NewSession.ccs");
}

FUNCTION CloseSession()
{
	LOG("CloseSession in Main is interpreting");
	LOG("_CLOSING_LEG_ = " + i2str(_CLOSING_LEG_ ));
	if (_CLOSING_LEG_ == _LEG_A_) {
		LOG("Closing LEG is LEG_A");
		EndCall(_LEG_B_);
	}
	else {
		LOG("Closing LEG is LEG_B");
		EndCall(_LEG_A_);
	}

	LOG("-------SESSION_ID:[" + i2str(_SESSION_ID_) + "]---------");
	LOG("Session has closed.");
	ReleaseSession();
}

FUNCTION AbortSession()
{
	EndCall(_LEG_A_);
	LOG("-------SESSION_ID:[" + i2str(_SESSION_ID_) + "]---------");
	LOG("Session has aborted.");
	ReleaseSession();
}



NewSession.ccs
EVENT NewCall()
{
	LOG("-------SESSION_ID:[" + i2str(_SESSION_ID_) + "]---------");
	LOG("NewCall received. Session has started!");
	LOG("Calling Number:" + _CALLING_NR_);
	
	AcceptCall(); 
	AnswerCall(); 
}

EVENT CallActive()
{
	LOG("Call is active");
	bool bRet = OpenAudioChannel(_LEG_A_);
	if (bRet == FALSE) {
		LOG("OpenAudioChannel returned FALSE");
		AbortSession();
	}
	
	// Play welcome audio
	PlayAudio(_LEG_A_, "Welcome");
	
	// Change voice directory for selected language
	ChangeLanguage();
	
	// obtaion the balance from billing server
	// 8.62 Euro
	g_CreditAmountInt = 8;
	g_CreditAmountDec = 62;
	// Play the amount to caller
	PlayAmount();
	
	// Make an authorization request and obtain the maximum call duration
	// Check out the sample radius request
	g_nMaxCallDuration = 600; // second

	LOG("Starting call to: " + _CALLED_NR_);
	StartCall(_LEG_A_, _LEG_B_, _CALLED_NR_);
	RunScript("Prepaid\\Ringing.ccs");
}

FUNCTION PlayAmount() 
{
    LOG("Credit Int:" + i2str(g_CreditAmountInt));
    LOG("Credit Dec:" + i2str(g_CreditAmountDec));

    PlayAudio(_LEG_A_, "SayBalance"); // You have
    if (g_CreditAmountInt > 0) {
        PlayCredit(_LEG_A_, g_CreditAmountInt, "Say_Euro");
    }
    if (g_CreditAmountDec > 0) {
        PlayCredit(_LEG_A_, g_CreditAmountDec, "Say_Cent");
    }
}

FUNCTION ChangeLanguage()
{
	// Press 1 for German, 2 French, 3 Spanish
	string strDigit = GetDigits(_LEG_A_, 1, "Language_Option");
	if (strDigit == "1") {
		_LANGUAGE_ = "german";
	}
	if (strDigit == "2") {
		_LANGUAGE_ = "french";
	}
	if (strDigit == "3") {
		_LANGUAGE_ = "spanish";
	}
}

EVENT CallEnd() 
{
	// BYE received
	LOG("CallEnd in newsession");
	AbortSession();
}


Ringing.ccs
EVENT CallRinging()
{
	g_PlayingRinging = TRUE;
	PlayBackgroundAudio(_LEG_A_, "Ringing", TRUE, 2);
}

EVENT CallAnswered()
{
	LOG("CallAnswered in Ringing is interpreting");
	if (g_PlayingRinging == TRUE) {
		g_PlayingRinging = FALSE;
		StopBackgroundAudio(_LEG_A_);
	}
	
	CloseAudioChannel(_LEG_A_);
	JoinLegs(_LEG_B_, _LEG_A_);
	RunScript("Prepaid\\CallMonitor.ccs");
}

EVENT CallReject()
{
	LOG("CallReject in Ringing, Reject Cause: " + i2str(_RESPONSE_));

	if (g_PlayingRinging == TRUE) {
		g_PlayingRinging = FALSE;
		StopBackgroundAudio(_LEG_A_);
	}
	
	if (_RESPONSE_ == 404) {
		LOG("Called number is not found");
		PlayAudio(_LEG_A_, "DestinationNotFound");
	}
	if (_RESPONSE_ == 486) {
		LOG("Called number is busy");
		PlayAudio(_LEG_A_, "NumberIsBusy");
	}
	if ((_RESPONSE_ == 408) || (_RESPONSE_ == 480) || 
		(_RESPONSE_ == 484) || (_RESPONSE_ == 487)) {
		LOG("Called number does not answer");
		PlayAudio(_LEG_A_, "NoAnsver");
	}
	if (_RESPONSE_ == 500) {
		LOG("Interval Server Error (Sip Cause 500)");
		PlayAudio(_LEG_A_, "ErrorMessage");
	}
	AbortSession();
}

EVENT CallEnd()
{
	LOG("CallEnd in Ringing is interpreting");
	if (g_PlayingRinging == TRUE) {
		StopBackgroundAudio(_LEG_A_);
	}
	CloseSession();
}


CallMonitor.ccs
EVENT CallEstablished()
{
	LOG("CallEstablised in CallMonitor is interpreting");

	if (g_CallEstablished == TRUE) {
		RunScript("Prepaid\\CallMonitor.ccs");
	} 
	
	int nRet = 0;
	g_Pound = FALSE;
	g_IsTimerExpired = FALSE;
	g_strConnectTime = GetTime();
	g_CallEstablished = TRUE;
	LOG("Connect Time :" + FormatTime(g_strConnectTime, "%H:%M:%S.000 UTC %a %b %d %Y"));

	if (g_CreditTime >= 60) {
		LOG("First 60sec setted..." );
		g_iTimerId = StartTimer(g_CreditTime - 60, "LastMinWarning", TRUE);		
	}
	else {
		g_iTimerId = StartTimer(g_CreditTime, "TimerExpired", TRUE);
	}

	LOG("Timer Active");
}

EVENT LastMinWarning()
{	
	LOG("LastMinWarning occured");	
	RunScript("Prepaid\\LastMinuteWarning.ccs", "UserEvent");
}

EVENT TimerExpired()
{	
	LOG("TimerExpired in CallMonitor is interpreting");
	string strTime = GetTime();
	LOG("Time: " + FormatTime(strTime, "%H:%M:%S.000 UTC %a %b %d %Y"));

	// Close Both LEG
	EndCall(_LEG_IVR_);
	//RadiusStopAccounting();
	ReleaseSession();
}

EVENT LastMinCallback()
{	
	LOG("LastMinCallback is interpreting");	

	if (g_iTimerId != 0) {
		LOG("Old Timer stopping." + i2str(g_iTimerId));
		StopTimer(g_iTimerId);
		g_iTimerId = StartTimer(60, "TimerExpired", TRUE);
	}
	RunScript("Prepaid\\CallMonitor.ccs");
}

EVENT CallReject()
{
	LOG("CallReject in Ringing is interpreting");
	LOG("Reject Cause: " + i2str(_RESPONSE_));

	if (g_CallEstablished == TRUE) {
		LOG("Reject message for re-INVITE ");
		EndCall(_LEG_B_);
	}

	if (_RESPONSE_ == 404) {
		LOG("Called number is not found");
		PlayAudio(_LEG_A_, "DestinationNotFound");
	}
	if (_RESPONSE_ == 486) {
		LOG("Called number is busy");
		PlayAudio(_LEG_A_, "NumberIsBusy");
	}
	if ((_RESPONSE_ == 408) || (_RESPONSE_ == 480) || 
		(_RESPONSE_ == 484) || (_RESPONSE_ == 487)) {
		LOG("Called number does not answer");
		PlayAudio(_LEG_A_, "NoAnsver");
	}
	if (_RESPONSE_ == 500) {
		LOG("Interval Server Error (Sip Cause 500)");
		PlayAudio(_LEG_A_, "ErrorMessage");
	}
	AbortSession();
}

EVENT CallEnd()
{
	LOG("CallEnd in CallMonitor is interpreting");
	//RadiusStopAccounting();
	CloseSession();
}

EVENT OnDigit()
{
	LOG("OnDigit in CallMonitor is interpreting");
	SendDigit(_LEG_B_, _DIGIT_, _DIGIT_DURATION_);
}


LastMinuteWarning.ccs
EVENT UserEvent()
{
	LOG("LastMinWarning::UserEvent is interpreting");

	JoinLegs(_LEG_IVR_, _LEG_B_);
	JoinLegs(_LEG_IVR_, _LEG_A_);
	
	bool bRet = OpenAudioChannel(_LEG_A_);
	if (bRet == FALSE) {
		LOG("LastMinWarning::OpenAudioChannel returned FALSE");
	} 
	
	// Make the last minute announcement
	PlayAudio(_LEG_A_, "YourLast60Sec");
	
	CloseAudioChannel(_LEG_A_);

	JoinLegs(_LEG_B_, _LEG_A_);
	JoinLegs(_LEG_A_, _LEG_B_);
}

EVENT CallEstablished()
{
	LOG("CallEstablised in LastMinWarning is interpreting");
	RunScript("Prepaid\\CallMonitor.ccs", "LastMinCallback");
}

EVENT CallEnd()
{
	LOG("CallEnd in CallMonitor is interpreting");
	//RadiusStopAccounting();
	CloseSession();
}



BUILDING BROADBAND IP TELEPHONY SERVICES


It is possible to use Creacode SIP Application Server as a B2BUA or a stateful SIP proxy. It is ideal solution, if operator does not need to play voice prompts but need to retain full supervision of call sessions while communicating with billing servers or any external applications in call sessions.
                          
	      CALLER                CREACODE SAS                CALLEE
		|                        |                        |
		|                        |                        |
		|>REGİSTER ------------->|<------------- REGISTER<|
		|                        |                        |
		|<--------------- 200 Ok<|>200 Ok---------------->|
		|                        |                        |
		|>INVITE (sdp)---------->|                        |
		|                        |                        |
		|<----------- 100 TRYING<|                        |
		|                        |                        |
		|                        |>INVITE (sdp)---------->|
		|                        |                        |
		|                        |<---------- 180 RINGING<|
		|                        |                        |
		|<-----------180 RINGING<|                        |
		|                        |                        |
		|                        |<----------(sdp) 200 Ok<|
		|                        |                        |
		|                        |>ACK ------------------>|
		|                        |                        |
		|<----------(sdp) 200 Ok<|                        |
		|                        |                        |
		|>ACK------------------->|                        |
		|                        |                        |
		|>re-INVITE (sdp)------->|                        |
		|                        |                        |
		|<----------- 100 TRYING<|                        |
		|                        |                        |
		|                        |                        |
		|                        |>re-INVITE (sdp)------->|
		|                        |                        |
		|                        |<----------(sdp) 200 Ok<|
		|                        |                        |
		|                        |>ACK ------------------>|
		|                        |                        |
		|<----------(sdp) 200 Ok<|                        |
		|                        |                        |
		|>ACK------------------->|                        |
		|                        |                        |
		|                        |<------------------ BYE<|
		|                        |                        |
		|                        |>20O Ok --------------->|
		|                        |                        |
		|<------------------ BYE<|                        |
		|                        |                        |
		|>200 Ok --------------->|                        |
		
	
Please contact us for any question or further details: info@creacode.com.tr