# Placing and receiving calls: inoutcta

Use inoutcta to:

- Demonstrate the operation of all NMS CAS call control TCPs, either on a live trunk (placing and receiving calls while connected to the PSTN) or through the MVIP bus (for testing purposes on digital trunks only).

- Provide an example of C code implementation of a two-way trunk application (that can both place and receive calls) using Natural Access.

#### Usage

inoutcta [options]

General Options

Use this option... | To...
--- | ---
-? | Display a Help screen and terminate inoutcta.
-b board_# | Specify the board number. Default: board 0
-p protocol | Specify the name of the TCP. Refer to the NMS CAS for Natural Call Control Developer's Manual for a list of available protocols.
-s slot | Specify the MVIP timeslot. Default is 0. The MVIP stream is automatically selected by the program, according to the type of board it is running on.
-t number | Exploit the multi-threaded Natural Access programming model. A number of threads are created that either place or receive calls. The first thread starts on the timeslot specified with the -s option. The remaining threads use the subsequent timeslots.
-v level | Specify the verbosity level of messages printed on screen. level can be any of the following values:
Value | Description
0 | Display error messages only.
1 | Display errors and unexpected high-level events.
2 | Display errors and all high-level events (default).
3 | Display errors and all events.

Inbound options

Use this option... | To...
--- | ---
-a mode | Accept the inbound calls before answering or rejecting. Valid values for mode include:
Value | Description
1 | Accept and play ring back.
2 | Accept and remain silent until further command.
3 | Accept with user audio and play a voice file.
4 | Accept with user audio and detect DTMFs.
Note: Modes 2, 3, and 4 are not supported for analog trunks.
-B rate | Specify the rate of billing. Applies to digital trunks only. Valid values for rate include:
Value | Description
0 | Free call.
N | Normally billed call.
-g | Emulate a gateway application. The user controls the timing of the incoming call that is accepted or rejected. Applies to digital trunks only.
-j mode | Reject the inbound calls. Valid values for mode include
Value | Description
1 | Reject by playing reorder tone or equivalent protocol signal.
2 | Reject by playing busy tone or equivalent protocol signal.
3 | Reject by playing ring tone.
4 | Reject by playing user audio.
-i | Enable interactive dialing (valid for outbound or trunk protocols only).
-r rings | Specify the number of ring tones to play before answering a call. Default: 2.

Outbound options

Use this option... | For...
--- | ---
-n number_to_dial | Outbound or two-way protocols only. Default: 123 number_to_dial must be formatted appropriately for the TCP.

#### Hardware requirements

inoutcta can work with any NMS board with a processor and DSPs.

Note: Some TCPs supported by inoutcta do not work with all boards.

#### Software requirements

To use inoutcta, you need Natural Access and a protocol. Refer to the NMS CAS for Natural Call Control Developer's Manua l for a description of the protocols.

#### Description

To place and receive calls, inoutcta uses CAS protocols such as the MFC-R2 TCP (mfc0.tcp). The MFC-R2 TCP can handle inbound calls, receive a dial command, and seize the line for an outbound call. Optionally, the demonstration program can act as either an inbound application or an outbound application, for use on one-way lines.

inoutcta performs the following actions:

Step | Action
1 | It loads the user option parameters that the TCP will use (the parameter files provided with NMS CAS). The parameter files are adi xxx.par nccx xxx.par where xxx represents the first three characters of the protocol. inoutcta also loads the following parameter files: ncc x cas.par ncc x adi.par These files are located in the \nms\ctaccess\cfg directory.
2 | It starts the TCP specified on its command line, configuring it using the parameters loaded in Step 1.
3 | It either places a call or waits for one, depending on the -i command line argument.
4 | If commanded to dial out (outbound behavior), it dials either automatically or interactively, depending on the -i command line argument. If the demonstration program is commanded to wait for a call (inbound behavior): It waits for an incoming call. When a call is received, the program prints out the received call information (such as caller ID information on analog trunks, if enabled). If instructed by the user, it accepts the call through one of the standard call acceptance procedures. The program answers or rejects the call according to the -j mode command line option. If the call is answered, the program plays back the digits received. The program plays another prompt asking the user for a DTMF specifying the action to take next: playing a voice file, recording a voice file, or hanging up. The program starts the DTMF detector and waits for a tone. If the tone does not come, it hangs up. If the tone arrives, the demonstration program performs the action that the tone specifies, then hangs up.
5 | If the demonstration program seizes the line first (outbound behavior), the program takes the following actions: It dials the number specified by the user. When the call is answered, it starts recording. When silence is detected, it stops recording and plays the DTMF tone meaning "record" for its inbound counterpart (for back-to-back operations). Note: To run the inoutcta application in back-to-back mode on analog lines, make connections through the switch or the PBX to obtain the loop start signaling necessary for the loop start TCP. The program starts playing back the newly recorded voice file. When playing is completed, it hangs up. inoutcta hangs up if the caller hangs up at any time. inoutcta displays the Natural Access messages it receives on the screen according to the verbosity level (-v command line option).

The following table lists the interactions between two inoutcta applications in which one acts as an inbound application, and the other as an outbound application:

Outbound |  | Inbound
--- | --- | ---
Place call. |  | Wait for call. Optionally, may accept the call.
Get connected. |  | Answer call.
Record. |  | Speak prompt on both analog and digital trunks and digits on a digital trunk.
Send DTMF. |  | Detect DTMF.
Play back recorded file. |  | Record voice.
Wait for hang up, or hang up. |  | Wait for hang up, or hang up.

The demonstration program illustrates both the one-context-per-process Natural Access programming model and the multi-threaded model with one context per thread. The functionality does not change in either case.

## Program structure and coding features

inoutcta is based on the asynchronous programming model implemented by Natural Access. Some function calls in the program are found in the ctademo library supplied with Natural Access to provide users with examples of how to use the APIs.

ctademo functions have names starting with Demo. For example, DemoHangNCCup uses nccDisconnectCall and then waits for the result of the call (either SUCCESS or DISCONNECT) before returning. Most ctademo functions are wrappers that enclose the corresponding NCC service function or ADI service function and wait for an event to terminate the function, either by signaling that the function was successful or by signaling a failure. In this way, they transform an asynchronous wait for an event into a synchronous function call.

## main function

The main function of inoutcta first defines the list of Natural Access service managers that the application needs. Then it parses its command line arguments, and assigns the corresponding values to its variables. The function then checks that none of the user options are inconsistent with each other, and warns the user if it finds a problem. Then it registers an error handler with Natural Access and starts Natural Access.

main then queries the board to learn the MVIP stream DSPs are on, and launches the demonstration loop in one of two ways, depending on whether -t (the use threads option) is specified on the command line.

If the -t option is not specified, the demonstration program calls the RunDemo function. Otherwise, the demonstration program launches RunDemo a number of times, as many as the argument to the -t option. All threads share the same parameters.

## Opening the driver, context, and protocol

In inoutcta, RunDemo defines the list of Natural Access services needed by the thread. It then calls DemoOpenPort, a function from the ctademo library. DemoOpenPort opens the Natural Access application queue, attaching all defined service managers. It then creates a context and opens the defined services on the new queue.

RunDemo then calls ctaLoadParameterFile, a function that loads a parameter file containing parameters to configure the TCP for its specific implementation.

Parameter files are found in the following locations:

Operating system | Directory
Windows | \nms\ctaccess\cfg\
UNIX | /opt/nms/ctaccess/cfg/

If the parameter file is not found, RunDemo uses the TCP's default values.

Next, RunDemo modifies one or more parameters in the standard NCC service or ADI service start parameter structures. To do so, it uses ctaGetParms to retrieve the current defaults, and then explicitly sets the parameter presented in the following table. It then starts the TCP on the opened context. To do so, it calls nccStartProtocol with

- A NULL pointer for the TCP-specific parameter structure argument, so that the TCP uses the TCP-specific parameters just loaded into the process parameter space.

- A pointer to the changed NCC_ADI.START structure to load these parameters.

The following Natural Access parameters change:

Parameters | Description
--- | ---
NCC.X.ADI_START.mediamask | Tells the TCP what functions are to be started and ready for the application to use in the conversation state. Functions that can be started by the TCP include DTMF detection, energy detection, silence detection, and echo cancellation.
NCC.START.eventmask | Programs the TCP to send to the application or retrieve a number of informational events. These events can be useful to determine the state of calls.

inoutcta enables all informational events. The informational events are:

Event | Description
--- | ---
NCCEVN_CALL_PROCESSING | For outbound calls. Reports when all the digits have been delivered to the telephone network.
NCCEVN_REMOTE_ALERTING | For outbound calls. Reports when the distant terminal is ringing.
NCCEVN_REMOTE_ANSWERED | For outbound calls. Reports when the remote terminal has answered.
NCCEVN_BILLING_INDICATION | For outbound calls. Reports billing pulses. These are signaling pulses that can be received from a PSTN switch while the call is connected to signal that a unit of cost has been billed to the call. (Applies to digital trunks only.)
NCCEVN_CALL_STATUSUPDATE | Reports asynchronous changes on digital trunks in the NCC_CALL_STATUS structure. This happens because of network events that the application may need, but does not modify the state of the call. (Applies to digital trunks only.)

## MyReceiveCall and MyPlaceCall

Once the protocol is started on the board, depending on the type of TCP, RunDemo is ready to accept incoming calls or dial outgoing calls. MyReceiveCall is invoked repeatedly. This function performs all call control and hangs up the line when the call is completed.

If the TCP is only outbound (only places outgoing calls), the loop does the following:

- If the -i option (for interactive dialing) is specified on the command line, the loop prompts the user to press a key, and starts waiting for the keyboard event. When the user presses a key, the loop calls the function MyPlaceCall to dial out a call.

- If the -i option is not specified, the loop immediately calls the function MyPlaceCall to dial out a call.

If the TCP is bidirectional, the call comes in while the loop is waiting for the user to press a key. MyReceiveCall is called since this is a legal event for a bidirectional trunk.

### MyReceiveCall

MyReceiveCall performs the following actions:

1. Checks to see why it has been invoked.
   If MyReceiveCall was invoked because an incoming call was detected while the program was waiting to place an outgoing call, there is no need to wait further for a call. MyReceiveCall queries Natural Access to get information about the incoming call, by invoking nccGetCallStatus.
   The information includes the following:

Information | Description
--- | ---
called number | Called number digits.
calling party number | ANI (automatic number identification) digits.
calling name | Calling party name.
user category | For MFC-R2, MFS, EAM, and R1.5 TCPs, shows the user category of the calling party (for example, normal subscriber, operator, test equipment).
toll category | Usually the same as the user category, but, in some countries, it can have a different meaning (toll category); for MFC-R2 and EAM TCPs only.
calling number presentation indicator | ANI digits might not be available because of interworking of different protocols with different features in the call path or ANI presentation might be restricted. This value is used even when no ANIs are present, when the TCP does not support ANI reception, and when the TCP parameters specify that ANIs are not requested. Possible values include: 0 = Calling number presentation allowed (default) 1 = Calling number presentation restricted 2 = Calling number not available

These attributes are stored in the NCC_CALL_STATUS data structure. The fields that need to be completed will vary depending on the protocol and the country. For more information, refer to the NMS CAS for Natural Call Control Developer's Manual.

If a purely inbound TCP is active and MyReceiveCall is called, or if the TCP signals to the application that the line has been seized and that call setup has begun, the application must wait for the incoming call setup to be completed. The function does so by waiting for the appropriate event (NCCEVN_INCOMING_CALL). Once this event is detected, the function calls nccGetCallStatus to get the digit information.

On digital trunks, while waiting for NCCEVN_INCOMING_CALL, MyReceiveCall may receive the NCCEVN_RECEIVED_DIGIT event which indicates that a digit has arrived in the queue. MyReceiveCall displays a message to the screen that indicates the digit.

MyReceiveCall may also receive NCCEVN_CALL_DISCONNECTED, indicating that the calling party has hung up. MyReceiveCall jumps to the label hangup_in to hang up the call.

2. On digital trunks, MyReceiveCall can optionally set the billing rate of the incoming call. This is not supported by all CAS protocols. For more information, refer to the NMS CAS for Natural Call Control Developer's Manual. The TCP replies with one of the following events:

Error | Description
--- | ---
NCCEVN_BILLING_SET | The billing rate has been set. Refer to the value field to check if the network accepted the requested billing rate.
NCCEVN_PROTOCOL_ERROR | The protocol does not support the set billing operation.
NCCEVN_SEQUENCE_ERROR | The protocol supports the set billing operation, but the operation was requested at a time when it was no longer allowed by the protocol, for instance after the call was accepted (with the default billing indication).

3. MyReceiveCall can optionally accept the call before answering or rejecting. The three modes of accept are:

Mode | Description
--- | ---
NCC_ACCEPT_PLAY_RING | Accepts the call and plays ring indefinitely. This may be important for applications that intend to answer the call, but need time to process the information associated with the incoming call. This is the only available option for analog loop start TCPs.
NCC_ACCEPT_USER_AUDIO | Accepts the call and plays a voice message on the line. This may be necessary for IVR applications that want to explain features of the service offered, without billing the caller. An option of this accept mode is also demonstrated, that of detecting DTMF tones at this stage. This might not be allowed by the network, as typically at accept time the voice path is connected only in one direction, from the NMS board to the caller, and not in the other direction. This option is not supported for analog protocols.
NCC_ACCEPT_PLAY_SILENT | Accepts the call and remains silent. Use this option for trunk-to-trunk switching applications. This option is not supported for analog protocols.

MyReceiveCall answers the call or rejects it depending on the -j command line option.

-j Argument | Action
--- | ---
1 = NCC_REJ_PLAY_REORDER | Rejects the call using DemoRejectCall, directing the TCP to signal that the number called is not allocated.
2 = NCC_REJ_PLAY_BUSY | Rejects the call using DemoRejectCall, which calls nccRejectCall directing it to signal that the line is busy. The MFC-R2, MFS, and EAM TCPs do this by sending a special MF tone in the compelled sequence. (Other TCPs use methods that are protocol-specific.) DemoRejectCall waits for the event signifying that the caller has hung up (NCCEVN_CALL_DISCONNECTED).
3 = NCC_REJ_PLAY_RINGTONE | Rejects the call by playing ring until the other side hangs up.
4 = NCC_REJ_USER_AUDIO | Rejects the call using CustomRejectCall, which plays a special information tone (SIT). CustomRejectCall defines the SIT and calls nccRejectCall with the argument NCC_REJ_USER_AUDIO. This call tells the TCP to reject the call and open the DSP resource to the application. The custom audio can then be played on the line. CustomRejectCall plays the defined SIT and monitors the event queue for NCCEVN_TONES_DONE with reason NCC_REASON_RELEASED, and NCCEVN_CALL_DISCONNECTED. When both events are received, the function terminates.
No -j option is specified | Answers the call. It calls nccAnswerCall with an argument that makes the TCP play three rings before answering automatically. MyReceiveCall waits for a user's keystroke. If the keystroke is detected, MyReceiveCall calls nccAnswerCall again. The TCP answers the call immediately.

4. If MyReceiveCall answers the call, it allows the demonstration program to talk either with a human being on a telephone or with a corresponding outbound application. MyReceiveCall performs the following operations:

- Plays voice files announcing the called number and the calling number, if available. Applies to digital trunks only.

- Plays another voice file with a menu, prompting the user to enter a DTMF tone from the keypad to do one of the following: record a voice file, play a previously recorded voice file, or hang up.

5. To play voice files, it calls the CTADEMO function DemoPlayFile, which opens a voice file and calls adiStartPlaying to play it. MyReceiveCall does the following:

- Waits for a DTMF tone to be detected. To do so, it calls DemoPromptDigit, which sets three-second timeouts between digits, and calls adiCollectDigits twice in an attempt to get the digits. If a DTMF is not detected, MyReceiveCall hangs up.

- If a DTMF digit is detected, MyReceiveCall does what the DTMF tones direct it to do, and then hangs up. (If the command was to hang up, it hangs up immediately.) If no voice file exists, MyReceiveCall plays a default voice file (that is, there is nothing to play).

### MyPlaceCall

MyPlaceCall performs the following actions:

Step | Action
1 | Tries to place a call to the number that the user specified in the command line. To place the call, MyPlaceCall invokes nccPlaceCall with the digits to call, and waits for events. Possible events include:
Event | Description
--- | ---
NCCEVN_PLACING_CALL | Placing a call.
NCCEVN_CALL_PROCEEDING | All digits delivered to the network.
NCCEVN_REMOTE_ALERTING | Outbound ring detected.
NCCEVN_STATUSINFO_UPDATE | Call status message received. Applies to digital trunks only.
NCCEVN_REMOTE_ANSWERED | Outbound answer detected.
NCCEVN_CALL_DISCONNECTED | Call control is in disconnected state.
NCCEVN_CALL_CONNECTED | Call control is in connected state.
2 | When the call is connected, MyPlaceCall starts recording whatever is on the line, waiting for a period of silence to stop recording. This operation is designed both to interact with a human being ("Hello") and to interact with the MyReceiveCall function, which speaks a little longer. To record the voice on the line, MyPlaceCall calls vceRecordMessage, which opens a voice file to receive the data and then invokes adiStartRecording.
3 | If silence is detected, MyPlaceCall first sends a DTMF tone, by invoking adiStartDTMF. This is strictly to interact with MyReceiveCall. The DTMF tone is the one that tells it to start recording.
4 | MyPlaceCall invokes MyPlayMessage to play back what was just recorded. When playback is finished, MyPlaceCall calls DemoHangUp to hang up.
5 | On digital trunks, if billing pulses are detected, MyPlaceCall displays a message for each pulse, with a pulse count (if billing pulse detection is enabled).

## Using WaitForAnyEvent

WaitForAnyEvent waits for an event to arrive from an event queue in use by the application. The function is operating system specific, with #ifdefs used to differentiate among different operating systems. Although Natural Access provides an operating system independent function to collect events, the demonstration application must still collect the user's keystrokes. Collecting user keystrokes must be performed differently on different operating systems.