Real-Time Applications can be written using the CG/PL language.
When a Task is created to process an incoming call, the main entry of
the specified CG/PL application program is executed.
Real-Time Applications can use CG/PL external-declarations.
When a code section (a procedure or a function) declared as external is called,
a file with the code section name and the .sppi extension is loaded from the current
Environment. The program code in this file must contain the code section with the specified name
and of the proper type (a procedure or a function).
The program code in an .sppi file may contain other code sections as well.
Real-Time Applications written in the CG/PL language can use the following built-in procedures and functions.
Input
- ReadInput(timeOut)
- This function is used to receive external Task communications: DTMF symbol entered
by the peer, signals sent by the peer, and Events sent by other Tasks and by the system itself.
See the CG/PL Events section for the detail.
The timeOut value should be a number specifying the maximum wait period (in seconds).
If the timeOut value is zero, the function checks for pending digits and events, without any waiting.
The function returns:
- a string with the first DTMF symbol in the Task DTMF buffer.
The symbol is removed from the Task buffer.
- a dictionary with the first waiting Event. The Event is
removed from the Task Event queue.
- a null-value if no DTMF symbol and no Event was received during the specified time period.
When the peer disconnects, the Task receives a Disconnect Event from the system (this Event dictionary
does not contain the .sender element).
- IsDisconnectEvent(input)
- This function returns a true-value if the input value is a Disconnect Event.
//
// Sample: ReadInput()
// Accept an incoming call (stop if it's not possible).
// Play the PressPound media file.
// Wait for any input for up to 5 seconds.
// If the "pound" ("#") symbol was entered,
// play the Good media file.
// Otherwise,
// play the Bad media file.
// Stop.
//
entry Main is
if AcceptCall() != null then stop; end if;
PlayFile("PressPound");
PlayFile(ReadInput(5) == "#" ? "Good" : "Bad");
end entry;
|
|
Signals
- RejectCall(responseCode)
- This procedure rejects an incoming session if there is one:
the Task should be in the incoming or provisioned mode.
The responseCode value should be a numeric value between 400 and 699.
This number is sent back to the caller as the Signal Response code.
If the code 401 is sent back, and the request came
from outside the CommuniGate Pro Server (via the SIP protocol), the
SIP server module adds the proper fields to the response to facilitate client Authentication.
The Task is placed into the disconnected mode.
- AcceptCall()
- This function accepts an incoming session, if there is one:
the Task should be in the incoming or provisioned mode.
This function returns a null-value if the session is accepted successfully, and the Task
is placed into the connected mode.
If a session cannot be accepted, this function returns an error code string,
and the Task is placed into the disconnected mode.
//
// Sample: AcceptCall()/RejectCall()
// If the current local time is not between 8:00 and 17:00,
// reject the call (with the 403 error code) and stop.
// Otherwise,
// accept the call (stop if it is not possible)
// play the Welcome media file and stop.
//
entry Main is
currentTime = TimeOfDay(GMTToLocal(GMTTime()));
currentHour = currentTime / 3600;
if currentHour < 8 or currentHour >= 17 then
RejectCall(403); stop;
end if;
if AcceptCall() != null then stop; end if;
PlayFile("Welcome");
end entry;
|
|
- RedirectCall(newURI)
- This procedure redirects an incoming session, if there is one:
the Task should be in the incoming or provisioned mode.
The newURI value should be a string, or an array of strings. The incoming
session is redirected to the URI(s) specified and the Task is placed into the disconnected mode.
- ForkCall(newURI)
- This procedure redirects an incoming session, if there is one:
the Task should be in the incoming or provisioned mode.
The newURI value should be a string, or an array of strings. The incoming
session is directed to the URI(s) specified, and the current Task remains in the same state,
so it can accept, reject, redirect, provision, or fork this call later.
- ProvisionCall(startMedia,reliably)
- This function sends a provisional Response for an incoming session Request, if there is a pending one:
the Task should be in the incoming or provisioned mode.
If the startMedia value is not a null-vallue, then a Task Media Channel is created,
the Task is is placed into the provisioned mode and the Media Channel operations
(such as PlayFile) can be used to generate "ring-back tones".
If the reliably value is not a null-value, the response confirmation (SIP PRACK)
is requested, and the Task is suspended till a confirmation request arrives.
This function returns a null-value if the response is sent successfully.
If a provisional response cannot be sent, this function returns an error code string.
//
// Sample: RedirectCall()/ProvisionCall()
// Provision the call (stop if it is not possible).
// If the current local time is between 12:00 and 13:00,
// fork the call to user1 in the same domain.
// Play the "PleaseWait" media file.
// If the current local time is not between 8:00 and 17:00,
// redirect the call to user2 in the same domain, and stop.
// Otherwise,
// Accept the call (stop if it's not possible).
// Play the Welcome media file, and stop.
//
entry Main is
if ProvisionCall(true,true) != null then stop; end if;
currentTime = TimeOfDay(GMTToLocal(GMTTime()));
currentHour = currentTime / 3600;
if currentHour >= 12 and currentHour <= 13 then
ForkCall("sip:user1@" + MyDomain());
stop;
end if;
PlayFile("PleaseWait");
if currentHour < 8 or currentHour >= 17 then
RedirectCall("sip:user2@" + MyDomain());
stop;
end if;
if AcceptCall() != null then stop; end if;
PlayFile("Welcome");
end entry;
|
|
Note: if a pending incoming call has been cancelled, the Task receives a Disconnect Event, and
the Task mode changes to disconnected.
- StartCall(sendURI)
- This function initiates an outgoing session. The Task should be in the disconnected mode.
The sendURI value should be a string containing the URI to send a session request to, or a dictionary
containing the following string elements:
- "" (empty string)
- the URI to send a request to
- From (optional)
- the URI to use for the request From: field
This function returns an error code string if an outgoing call cannot be initiated.
If an outgoing call has been initiated successfully, the function returns a null-value,
and the Task starts to receive call progress Events from the system:
zero or more provisional response Events, followed by exactly one final response Event.
If the outgoing session has been established successfully, the Task receives
a final response Event without a parameter.
If the outgoing session has been established successfully, the Task receives
a final response Event with a parameter - the error code string.
- IsCallProvisionEvent(input)
- This function returns a true-value if the input value is a call provisional response Event.
Otherwise the function returns a null-value.
- IsCallCompletedEvent(input)
- This function returns a true-value if the input value is a call final response Event.
Otherwise the function returns a null-value. When a Task receives a final response Event, the call
signalling process has completed. If the Event has a parameter, the call has failed, and the
parameter contains the error code string.
- CancelCall()
- If a Task has a pending outoging call (initiated using the StartCall function), this
procedure cancels that call (the Task will not receive a final response Event).
- Disconnect()
- This procedure ends the active session, if any, and the Task is placed into the disconnected mode.
//
// Sample: StartCall()/Disconnect()
// Accept an incoming call (stop if it's not possible).
// Remember the caller URI.
// Play the CallBack media file.
// Disconnect();
// Call the caller back (stop if it's not possible).
// Play the IamBack media file, and stop.
//
entry Main is
if AcceptCall() != null then stop; end if;
fromWhom = RemoteURI();
PlayFile("CallBack");
Disconnect();
if StartCall(fromWhom) != null then stop; end if;
loop
input = ReadInput(3600);
exitif not IsCallProvisionEvent(input);
null;
end loop;
if not IsCallCompletedEvent(input) or else
input.parameter != null then stop; end if;
PlayFile("IamBack");
end entry;
|
|
- IsConnected()
- This function returns a true-value if the Task is in the connected mode.
- IsHalfConnected()
- This function returns a true-value if the Task is
in the connected or provisioned mode.
DTMF
Each Task has a DTMF buffer string. When a DTMF symbol is received either in an INFO Request
or as a media packet (via the Media Channel), the symbol is appended to this buffer.
- DTMF()
- This function returns a string with the current content of the DTMF buffer. The DTMF buffer
is not changed. Usually this function is not used, the ReadInput() function is used instead.
- ClearDTMF()
- This procedure empties the DTMF buffer.
- SendDTMF(symbol)
- This function sends a DTMF symbol to the peer.
The symbol value should be a string containing 1 DTMF symbol.
The function returns a null-value if a symbol was sent, or a string with an error code
if sending failed.
//
// Sample: ReadInput()/SendDTMF()
// Accept an incoming call (stop if it's not possible).
// Wait for an input for 10 seconds. If no input - stop.
// If a digit is entered
// play that digit, and send it back.
// (using "0" ... "9" files)
// If a star ("*") is entered,
// wait for a digit (for 3 seconds)
// and play the digit number square (2 digits)
// If a pound ("#") is entered or the Peer
// has disconnected, or any Event was sent, stop.
//
entry Main is
if AcceptCall() != null then stop; end if;
loop
input = ReadInput(10);
if input == "*" then
input = ReadInput(3);
if IsString(input) and input != "#" then
input = "*" + input;
end if;
end if;
exitif not IsString(input) or input == "#";
if Substring(input,0,1) != "*" then
PlayFile(input);
void(SendDTMF(input));
else
input = Number(Substring(input,1,1);
product = input * input;
PlayFile(String(product/10));
PlayFile(String(product%10));
end if;
end loop;
end entry;
|
|
Media
- PlayFile(fileName)
- This procedure retrieves a file from its Application Environment and plays it. The
string parameter fileName specifies the file name. If the specified file name
does not contain a file name extension, supported extensions are added and tried.
The file should contain media data in one of the supported formats.
Playing is suppressed or interrupted if the session ends, if the DTMF
buffer is not empty, or if there is an Event enqueued for this Task.
- PlayFileInLoop(fileName,msec)
- This procedure is similar to the PlayFile procedure.
The msec parameter value should be a number.
This procedure plays the specified file for msec milliseconds, repeating
file in a loop if the file media playing period is shorter than the specified period. If
the msec parameter has a negative value, the file is played in a loop without
a predefined time limit.
Playing is suppressed or interrupted if the session ends, if the DTMF
buffer is not empty, or if there is an Event enqueued for this Task.
- Play(waveData)
- This procedure plays the waveData value which should be a datablock.
The datablock should contain media data in one of the supported formats.
Playing is suppressed or interrupted if the session ends, if the DTMF
buffer is not empty, or if there is an Event enqueued for this Task.
- PlayInLoop(waveData,msec)
- This procedure is the same as the Play procedure, but it can play the media data
in a loop, in the same way as the PlayFileInLoop procedure does.
- Record(timeLimit)
- This function records incoming audio data. The timeLimit value should be a positive
number, it specifies the maximum recording time in seconds.
Recording is suppressed or interrupted if the session ends, if the DTMF
buffer is not empty, or if there is an Event enqueued for this Task.
The function returns a null-value if recording was suppressed, or a datablock with the
recorded sound in the WAV format.
//
// Sample: Record()/PlayFile()/Play()
// Accept an incoming call (stop if it's not possible).
// Play the GreetingIs file.
// Read the current prompt from
// the MyGreeting.wav file in the Personal Site.
// Loop playing the greeting.
// if "1" is entered, rewrite the prompt file and quit
// if "2" is entered, play "Beep" and record the prompt.
//
entry Main is
if AcceptCall() != null then stop; end if;
PlayFile("GreetingIs");
prompt = ReadSiteFile("MyGreeting.wav");
loop
if IsData(prompt) then Play(prompt); end if;
input = ReadInput(10);
exitif not IsString(input) or else input == "#";
if input == "1" then
if WriteSiteFile("MyGreeting.wav",prompt) then
PlayFile("Goodbye"); stop;
end if;
PlayFile("Failure");
elif input == "2" then
PlayFile("Beep");
prompt = Record(30);
else
PlayFile("InvalidEntry");
end if;
end loop;
PlayFile("GoodBye");
end entry;
|
|
- StartBridge(taskRef)
- This function sends a special StartBridge Event to the specified Task asking it to
take over this Task peer media.
The taskRef value should be a task handle. It specifies the Task
to send the request to.
This function returns a null-value if the specified Task successfully
took over this Task peer media. Otherwise, the function returns an error code string.
The current Task is placed into the waiting state, and the target Task receives a special
StartBridge Event.
- IsStartBridgeEvent(input)
- This function returns a true value if the input value is a StartBridge Event.
Otherwise the function returns a null-value.
- RejectBridge(input)
- This function rejects the StartBridge request.
The input parameter value should be a StartBridge Event to reject.
The StartBridge function in the Task that has sent this StartBridge Event
exits the waiting state and it returns an error code string.
- AcceptBridge(input)
- This function builds a Media Bridge with the Task
that has sent it the StartBridge Event.
The input value should be a StartBridge Event to accept.
This function returns a null-value if the Media Bridge was successfully established.
Otherwise, the function returns an error code string.
The StartBridge function in the Task that has sent this StartBridge Event
exits the waiting state. That function returns a null-value if the Media Bridge is established,
otherwise, it returns an error code string.
When a Media Bridge is successfully established between a pair of Tasks, their peer
media are connected to each other. Tasks Media Channels are disconnected from their peers
and the Media Channel operations (PlayFile, Record, etc.) cannot be used.
A Task cannot use the StartBridge, AcceptBridge, and AttachMixer
functions while a Media Bridge is active.
- BreakBridge()
- This procedure removes the Media Bridge established by a successful completion of the
StartBridge or AcceptBridge function.
The Task Media Channel is reconnected to the peer media.
A special BreakBridge Event is sent to the "bridged" Task.
- IsBreakBridgeEvent(input)
- This function returns a true-value if the input value is a BreakBridge Event.
Otherwise the function returns a null-value.
When a Task receives a BreakBridge Event, it does not have to use the BreakBridge()
procedure, as the Media Bridge has been already removed.
If a Task disconnects its peer, or the Task peer disconnects itself, or a Task
stops (normally, or because of an error), and there is an active Media Bridge, this
Media Bridge is automatically removed.
//
// Sample: StartBridge()/AcceptBridge()/BreakBridge()
// Accept an incoming call (stop if it's not possible).
// Create a new Task to run the Caller code,
// and send it an Event with the URI to dial.
// Play the PleaseWait media file.
// Wait for a StartBridge Event from the Caller Task.
// Accept it and loop till the user disconnects.
//
// The Caller code:
// Receive a URI to call as an Event from the parent Task
// Connect to the URI and play the YouGotACall media file
// StartBridge with the parent, loop till the user disconnects
//
entry Caller forward;
procedure ControlBridge() forward;
entry Main is
if AcceptCall() != null then stop; end if;
callerTask = spawn Caller;
if callerTask == null or else
SendEvent(callerTask,"dial","sip:internal@partner.dom") != null then
PlayFile("Failure");
stop;
end if;
PlayFile("PleaseWait");
input = ReadInput(30);
if not IsStartBridgeEvent(input) or else
AcceptBridge(input) != null then
PlayFile("Failure");
stop;
end if;
// we have established a bridge
ControlBridge();
PlayFile("GoodBye");
end entry;
//
// Caller Task code
//
entry Caller is
// wait for a "dial" event from the main task
input = ReadInput(30);
if input == null or input.what != "dial" then stop; end if;
mainTask = input.sender;
// Calling the URI specified as the Event parameter
// If connection failed, send an Event back to the
// main task and quit
resultCode = StartCall(startEvent.parameter);
if resultCode != null then
void(SendEvent(mainTask,"result",resultCode));
stop;
end if;
// wait for any Event other than provisional ones
loop
input = ReadInput(3600);
exitif not IsCallProvisionEvent(input);
end loop;
// the parent has sent us "stop" - then we'll die immediately
if IsDictionary(input) and then input.what == "stop" then stop; end if;
if not IsCallCompletedEvent(input) or else input.parameter != null then
void(SendEvent(mainTask,"result","generic error"));
stop;
end if;
if StartBridge(mainTask) != null then
PlayFile("Failure");
stop;
end if;
// we have established a bridge
ControlBridge();
PlayFile("GoodBye");
end entry;
//
// Controlling the peer signalling:
// while the media is bridged:
// exit if the peer hangs up, dials "#"
// or if the bridge is removed
//
procedure ControlBridge() is
loop
input = ReadInput(3600);
exitif IsBreakBridgeEvent(input) or else
IsDisconnectEvent(input) or else input == "#";
end loop;
void(BreakBridge());
end procedure;
|
|
- AttachMixer(input)
- This function takes the peer media of the Task that has sent it a
StartBridge request, and attaches it to its own Media Channel.
The input value should be a StartBridge Event send to this Task.
This function returns a null-value if the other Task peer media is successfully
attached to this Task Media Channel. Otherwise, the function returns an error code string.
The StartBridge function in the Task that has sent this StartBridge Event
exits the waiting state.
That StartBridge function returns a null-value if that Task peer media is attached successfully.
Otherwise, that function returns an error code string.
- DetachMixer(taskRef)
- This function detaches the peer media of the specified Task from this
Task Media Channel.
The taskRef value should be a task handle.
The function returns a null-value if the peer media of the specified Task
was attached to this Task Media Channel, and if that peer media is successfully
reconnected back to the specified Task.
The specified Task receives a BreakBridge Event.
The function returns an error code string if the other Task peer media cannot
be detached.
The taskRef value can be a null-value. In this case, all other
Tasks peer media are detached from this Task Media Channel.
- MixerAttached()
- This function returns an array of task handles for all Tasks that
attached their peer medias to this Task Media Channel.
If this Task Media Channel does not have any other Task peer media attached,
this finction returns a null-value.
When a Task has other Task peer media attached to its Media Channel, all media
are placed into one conversation space (or a conference).
This Task cannot use the StartBridge or AcceptBridge functions.
Note: in certain cases the system may decide to convert an AcceptBridge
function operation into an AttachMixer function operation.
As a result, the BreakBridge operation can be used by a Task that has exactly
one other peer media attached to its Media Channel.
If a Task disconnects its peer, or the Task peer disconnects itself, or a Task
stops (normally, or because of an error), and there are other Task peer media
attached to this Task Media Channel, the system automatically detaches all of them.
Dialog
- RemoteURI()
- This function returns a string with the peer URI (taken from the dialog From/To addresses).
If there is no session in place, the function returns a null-value.
- LocalURI()
- This function returns a string with the Task URI.
- IncomingRequestURI()
- This function returns a string with URI of the pending incoming INVITE request. If there is no
pending incoming INVITE request, the function returns a null-value.
- RouteLocalURI(uri)
- This function tries to Route the E-mail address from
the specified URI. If the URI cannot be parsed, or the URI address cannot be routed,
or it routes to a non-local address (i.e an E-mail address hosted on a different system),
this function returns a null-value. Otherwise, the function returns the E-mail address
of the CommuniGate Pro user the original URI address is routed to.
This function allows you to correctly process all Forwarders,
Aliases, and other CommuniGate Pro Routing methods.
- RemoteIPAddress()
- This function returns an ip-address object the session establishment
request was received from or was sent to. This IP Address/port pair is the actual peer address
or the address of a proxy used to relay the peer signalling.
- RemoteAuthentication()
- This function returns a null-value if the session starting request was not authenticated,
or a string with the authenticated user E-mail address.
Services
Under Construction