VOIP Application Design Considerations

 

Regardless of the language you use to develop your VOIP application, there are a few software design considerations you must be aware of in order to achieve the best possible behavior and performance from the VOIP Media Engine. This section exists to help you better understand the execution nature of the media engine and to help you avoid multi-threaded deadlock situations.

The information discussed here applies equally to native code application development (C, C++, pascal, etc) and managed .NET code application development (Vb.NET, C#.NET, etc).

Application software communicates with the media engine using the published media engine API. There are no restrictions when using this API from normal application GUI threads or application worker threads.

The media engine communicates with the VOIP application software using a single "main callback handler". The media engine calls this application specified callback procedure anytime the media engine has event information for the application. Because the media engine is fully multi-threaded, the media engine thread context used to execute the application's callback handler will vary depending on what events are being sent to the VOIP application.


Note:

 

Most high performance VOIP applications will want to use the callback event mechanism in order to get the best possible performance and maximum call handling capability from the media engine. However, the media engine can be used in a polling mode where no callback handler is specified when the media engine is started. In this case, the application must use media engine API status procedures to poll the state of phone lines and other operations in order to determine proper application activity.

 
 
 

Application Thread Requirements

 

Figure 1 below shows the recommended threading layout of a VOIP application that will use the event callback mechanism. The VOIP application can have any number of threads in its process space (i.e. the GUI thread and any number of worker threads). Media engine API procedures can be called from whatever application thread your design requires in order to initiate specific media engine activities (like performing SIP registrations or making calls).



Figure 1:
Basic Media Engine Callback Model



When the application needs to perform a telephony operation (like initiating an outgoing phone call), it can do so using whatever thread of execution makes the most sense for the application. The application thread need only call the appropriate media engine API procedure from the application thread.

When the media engine sends events to the application, it will execute the application's callback handler. To allow the telephony engine to perform its tasks as smoothly and as quickly as possible, it is recommended that the event notifications received by your callback be put into a FIFO queue. Your application should then have one of its own worker threads process the FIFO event data as required.

 

 

IMPORTANT:

 

The event callback is non-reentrant. In other words, the media engine has serialized access to your callback event handler procedure. Your VOIP application must not call any media engine API procedures in the event handler  that will in turn generate further events. Any API procedure that can generate additional events cannot be called in the "main event handler" when processing the current event. If you do, your application will deadlock. For example: Calling any of the following API procedures directly from within the callback handler will most likely result in your application deadlocking: MakeCall(), MakeCallUri(), TerminateCall(), GoOffHook(), AbortIncomingCall(), BusyOutLine(), HoldLine(), ConferenceLine(), TransferLine(), TransferLineUri(), EnableSipRegisterServer() or DiableSipRegisterServer().

 
 

Figure 1 above shows how the media engine communicates with your application code. When the media engine has event information for your application, it executes your callback handler (i.e. the "main callback handler"). The primary goal of all application code executed in the callback handler is speed. Only perform the bare minimum of application associated tasks in the callback handler. If you adhere to this rule, you will experience the best possible performance from the media engine.

There are three classes of media engine events: PHONE_LINE_NOTIFICATION, GLOBAL_NOTIFICATION and IMMEDIATE_NOTIFICATION events.


IMMEDIATE_NOTIFICATION event must be fully processed in the callback event handler. When receiving these immediate events, the media engine is asking your application for information or assistance regarding some operation that is taking place. The type of application you are developing will determine if you have to handle any of the immediate events. All media engine APIs that are required for processing immediate events are designed to be called from within the callback handler procedure and will not deadlock your application.

PHONE_LINE_NOTIFICATION and GLOBAL_NOTIFICATION events should be "briefly processed" in the callback handler. When we say "briefly processed", we mean your VOIP application should perform as little processing of the event in the callback handler as possible. The preferred method to process these two classes of events are to gather the event data and any other status information for the event (using status related APIs like GetIncomingCallInfo(), GetOutgoingCallInfo() or GetActiveCallInfo()) and queue the event data to an application supplied event FIFO. This is shown in Figure 1.

Your VOIP application code should have a dedicated worker thread (ApplicationEventWorkerThread()) that does nothing until it detects that there is event data in the event FIFO. Once your ApplicationEventWorkerThread() executes, it can process the event data as required and call any of the needed media engine APIs without risking deadlock situations.