TABLE OF CONTENTS
3. Configuration file conf_demo.cfg
3.4. Section [Board parameters]
7.5. Object CSrlDevice and derived objects
8. Multithreading considerations
9.1. Releasing resources before exit
11. HMP and SR release versions compatibility
13. CnfConference state diagram (initialization)
14. CnfConference state diagram (add voice resource)
15. CnfDevice state diagram – initialization and shut down
16. CnfDevice state diagram – call control
17. CnfDevice state diagram –conferencing
The document is intended for a technical audience that has the knowledge of cnf Conferencing and R4 APIs.
The HMP CNF conference demo is a simple audio conferencing application that is implemented using CNF API from HMP Software. It is using GlobalCall API to handle call-control, Voice API to detect digits and play files and CNF API to maintain conferences. It is single threaded APP using SRL in polled mode.
CNF demo demonstrates the following features:
Use Microsoft C 6.0. Project name is CnfConferencingDemo.dsw.
Build debug version: make DEBUG=1 BUILD=_HMP31
Build release version: make
Build for Titusville: make BUILD=_HMP15
Build Debug version for Titusville: make BUILD=_HMP15 DEBUG=1
Add more compile flags, for example “-Wall”: make EXTRA_CXXFLAGS=”-Wall”
You can configure the following parameters in file conf_demo.cfg:
Contains common parameters:
Header Format: [Ipt <n>], where <n> is unique decimal number referred as ipt_id.
Contains IP front-end specific parameters:
This section contains PSTN front-end specific parameters.
Header Format: [Conference <n>], where <n> is unique decimal number referred as conf_id.
Parameters: PassCode, DetectDigits, DTMFClamping Tmo, VoiceParty, PrivateLog and BeepNotify. Each parameter except PassCode has default value and can be omitted. Passcode is mandatory, and must be unique across the file. Caller should enter this code followed by ‘#’ using DTMF digits in order to join conference. Parameters DetectDigits, DTMFClamping, BeepNotify and VoiceParty may have values Yes or No. DetectDigits specifies request to receive event GNFEV_DTMF_DETECTED. DetectDigits specifies request to clamp DTMF digits. VoiceParty is a request to include voice party into the conference in order to record it or play prompts. Currently, VoiceParty produces short beep when a party is added or removed to the conference. BeepNotify is request to notify automatically when party is added or removed to the conference (an alternative to the VoiceParty).
Tmo is maximum time that this conference is allowed to live with more than 0 parties (in seconds). Cnf demo will create separate conference for each section [conference] encountered in configuration file.
Example:
[Conference 12]
Passcode = 12345
DetectDigits = No
DTMFClamping = No
Tmo = 300 (max time in seconds)
BeepNotify=Yes
VoiceParty=No
PrivateLog=DBG
To start demo, execute program CnfConferencingDemo.
To end demo, press <Ctrl-C> or close console window. Be patient and wait until demo cleans up all resources correctly. Ungraceful stop may leave HMP software in improper state and cause failures next time when you run other HMP applications.
To join conference, call demo using SIP or H323 phone. Make sure demo parameters (coder, frame and protocol match your device). Example string to use: anything@146.152.10.10. Listen to the prompt and dial pass code for desired conference. You will hear short beep when somebody joins your conference if VoiceParty is enabled for this conference. Two short beeps indicate that a party has been removed and 3 short beeps indicate that conference timeout has expired and all conference parties will be closed immediately.
To bypass the prompt, use ‘c’ followed by conference code as party address when calling. For example, to join conference with pass code “1234”, call “c1234@146.152.10.10”.
You cannot start 2 instances of this demo on same host. You cannot use other SIP or H323 software (such as soft phone) on the same host unless other device can change default sip and H323 ports. In short, to use this demo you need at least 2 hosts or one host and one ip phone.
Class CGenLog is abstract class that implement generic Log interface. A pure virtual function doLog provides device specific output and should be implemented in every class inherited from CGenLog. Log object will send any particular message to the output device only its verbosity level is greater or equal to CGenLog::m_verbosity. Log objects can be “chained” via function CGenLog::DefineChainLog (CGenLog *). Each message sent to the log is also forwarded to the chained log.
Application is sending messages for logging using function CGenLog::Log (). Each log message contains:
There are 2 Log classes in this demo
· CFileLog uses disk file as output device.
· ConsoleLog uses logs to console window.
Application Log object is named glb_pAppLog. It chains File and Console logs. Macro GLBLOG is used to send messages to glb_pAppLog. Each device has its own private log. By default, it is set to glb_pAppLog, but can be set to private m_pPrivateLog based on configuration file settings. In this case, glb_pAppLog is also chained and each message goes to private log file, console and common log file. Private log file name is derived from device name, for example iptB1T1.log.
Example for using Log object:
pLog->Log (DBG, “CDetectCfg”, “%d = dx_close (%d)”, rc, handle);
Example line from log file:
15:26:11.998 DBG CDetectCfg 0 = dx_close (1)
This message contains timestamp, message type (DBG), object that sends this message (“CDetectCfg”) and message is “0 = dx_close (1)”.
Class ConfigFile implements generic configuration file processing methods and properties: Loading and tokenization. Class CnfDemoPrm implements specific configuration file reader for cnf demo.
Class CDetectCfg is a configuration detector and resource keeper. It detects dx, dti, ipt, ipm, and cnf devices. Enum DEVICE_TYPE represents device types. Each device type has 2 lists implemented in object CDeviceList: “used” and “unused”. Other objects can request and reserve device of specific type via CDeviceList::Reserve (). They can either specify device name to be reserved or just ask for any available device of specific type. CDeviceList::UnReserve () will return back ownership of the device to object CDetectCfg. Configuration detector sets initial stage “unused” list. Then Reserve () and UnReserve () simply move devices between these lists. Each device should be in closed state when it is reserved or unreserved. Each device is represented by its name (“dxxxB1C1”, “dtiB1T1” etc.). Object glb_pDetectCnf is a singleton instance of class CDetectCfg.
Example for reserving any available device with play/record capabilities:
const char *dev_name;
if (glb_pDetectCnf->Reserve (DEV_DX, &dev_name)) {
//… dev_name points to the name of reserved device
}
const char *dev_name = “dxxxB1C1”;
if (glb_pDetectCnf->Reserve (DEV_DX, &dev_name)) {
//… Returns true if dxxxB1C1 was reserved.
}
Unreserved devices can be re-used from other clients:
glb_pDetectCnf->UnReserve (dev_name)
Each call scenario is driven by state machine. The only way to advance state machine is to handle SRL event in the following sequence:
If requested action fails, then Recover action is executed and state machine is then advanced. State machine loop terminates when all objects reach its final states (device closed). Each state machine maintains its current state and is driven by 2 tables: “Event table” and “Action table”.
Event table is array of structures EVENT_STRU and describes what action to execute upon receiving event in any particular state. EVENT_STRU description:
int current_state; // If this is current state
int event; // and this event is received
int action; // then attempt this action
Action table is array of ACTION_STRU and describes how to advance state and recover (if needed) after executing action in some particular state.
ACTION_STRU description:
int current_state; // If this is current state
int action; // and this action has been executed
int state_if_pass; // then advance to this state (if action passed)
int action_if_fail; // or execute this action to recover (action failed)
Notes:
Example:
CSrlDevice is an abstract class has one or more SRL handles obtained via gc_Open, dx_Open, cnf_Open etc. It implements following methods:
CSrlDeviceContainer is inherited from CSrlDevice and represent collection of SRL devices and other SRL Device containers. It can be SRL device as well. For example, dtiB1 is collection of dtiB1T1, dtiB1T2 etc. and is SRL device at the same time. CSrlDeviceContainer implements AreYouHandle, ExitRequest and CheckTmo accordingly to affect all devices that it owns.
NtwkDevice is inherited from CSrlDevice and represent network front-end device routed to dx device. It implements GlobalCall and voice specific functions such as ClearDigits () or AnswerCall (), call scenario and appropriate state machine. Conference actions belong to this state machine as well, even if conference functions are implemented in other classes.
IptDevice is inherited from CSrlDevice and represent ipt front end. It contains media SRL handle as well and IP specific functions such as SetCoders () and SetDtmfTransfer ().
PstnDevice is inherited from CSrlDevice and represent PSTN front end.
CnfParty is inherited from CSrlDevice and represent Cnf party. This objects Implement Cnf party specific functions.
CnfConference is inherited from CSrlDeviceCintainer and represent Cnf conference. This objects Implement Cnf conference specific functions and state machine. It is collection of cnf parties as well.
CnfBoard is inherited from CSrlDeviceCintainer and represent Cnfboard. This objects Implement Cnf board specific functions and state machine. It is collection of cnf conferences as well.
glb_ConferencePool is collection of all conferences. It is used from Ntwk devices to search for appropriate conference based of caller input DTMF digits. The reason of having this object instead of using Cnfboard is that future releases may support multiple cnf boards.
CSrlThread is CSrlDeviceContainer. The function CSrlThread::TheThreadBody () is consistently pulling events from SRL event queue, searching for appropriate CSrlDevice and executing its HandleEvent (). Finding appropriate device is based on:
WaitSrlState is convenient function that executes TheThreadBody until all devices reach specific state or until specified timer expire.
Function OnIdle is executed any time when SRL event queue is empty. It is used to calculate timeouts for all devices.
This demo runs in single thread. Here are guidelines how to make it multithreading:
The following objects may need changes:
There are several reasons for conference demo to abandon current action and attempt to transit either to state S_RELAX (waiting for calls / conferences) or to state S_FINAL (closed): remote site disconnected; local operator request app to exit or alarm network condition was raised. Accordingly, conference demo can handle the following SRL events at any time:
When any of exit signals is received, state machine initially performs all necessary steps to transit to S_RELAX state. Then, if exit is requested it transits to S_FINAL state and if Alarm condition is set it transits to state S_WAIT_UNBLOCKED.
If request to exit happens when conference demo is in its way to drop the call anyways, cleanup procedures proceed theirs normal path. Otherwise, _EXIT state is provided for each state and application is simply transited to appropriate _EXIT state while still continues to wait for termination event.
Example 1:
GCEV_DISCONNECTED is received when conference demo plays greeting file (state S_PLAYGREET). Dx_stopch () is invoked and state machine advances to S_STOP_DX (“exit” state for all voice functions). Application still waits for TDX_PLAY, then invokes DropCall () and proceeds its normal way to tear down the call.
Example 2:
USREV_EXIT_REQUEST is received when conference demo answers the call (state S_ANSWER). DropCall () is possible at this point, but there are hard to handle glair conditions:
a) GCEV_ANSWERED and/or GCEV_DISCONNECTED may be already posted from the firmware and in theirs way to the app. They could be received after DropCall. State machine should be able to handle this sequence.
b) If GCEV_TASKFAIL is posted, we cannot decide was it negative response to AnswerCall that was posted before DropCall, or it is negative response to DropCall. In the former case we should wait termination event for DropCall, in the later case we should not.
That’s why, better approach is to wait until AnswerCall completes and then initiate exit procedures. Accordingly conference demo transits to S_ANSWER_EXIT state. Subsequent GCEV_ANSWERCALL or GCEV_TASKFAIL will trigger DropCall () and application proceeds its normal way to tear down the call.
Application should release following resources to cleanup current call and get ready to the next call (or exit):
There are 2 ways of exiting this demo: As a response to external signal, or as a result of internal error. They both call global function glb_exit_request (). Application performs all necessary steps to exit gracefully:
There are 3 ways of tear down the call: As a response to remote disconnect, as a result of conference timing out, or as part of exiting procedure initiated from operator. Application performs all necessary steps to exit gracefully:
File win_unix.h is used to adjust all differences. All other files are identical for Linux and Window.
File product_versions.h is provided to adjust possible differences in feature releases and to make this demo backward and forward compatible (at source code level). Preprocessor constant _HMP30 is defined in project settings for this purpose. In feature GMP releases and for SR releases, it may be changed accordingly. _HMP3.1 is used HMP 3.1 release; _HMP15 – for Titusville.





