SEPTEMBER 1994 VOLUME 6 NUMBER 4
INDEX
Telephony SDK Services for PC Telecommunications
Like any software developer, I often try to dream up a software idea that hasn't already
been written by 10 or 20 other companies. I have found the solution to this problem; for the first
time I can work on a project that hasn't been done a thousand times over. I recently joined the
Developer Support group at Novell and was given responsibility for supporting the Telephony
SDK, so I started diving into the realms of PC telecommunications. I'll give you a brief
description of the Telephony SDK and the services it provides.
I'm not going to describe all of the requirements for running Novell NetWare Telephony
Services on Novell NetWare. These requirements are fully explained in the January and
February, 1994 editions of Novell's Application Notes. (Call 1-800-377-4136 for information on
Application Notes). Once you have the NetWare Telephony Services (TSERVer) installed and
functioning, assuming you have the Telephony Services API (TSAPI) SDK, you can begin
writing TSAPI applications. What fun it is to run a program that can call someone from your
desk without even touching your phone! And what frustration fellow engineers feel as you ring
their phones over and over again just to see your program in action! But enough of that--what
can the Telephony SDK actually do?
How TSAPI Works
As shown in Figure 1 on page 1, TSAPI is actually composed of two parts. The first part is the
TSERVer piece, a NetWare Loadable Module (NLM) for the NetWare file server. This piece
responds to requests made by client workstations that want Telephony services performed. Then
the TSERVer formats these requests correctly and passes them on to the second part of TSAPI, a
Private Branch Exchange (PBX) device driver (the software portion that transfers the requests
from the NetWare file server to the phone control system). Based on the PBX hardware you
have installed, you will have a different PBX driver loaded on your NetWare file server.
However, the TSERVer NLM remains the same.
The TSERVer NLM and the PBX driver work together to provide telephony functionality,
but some of these features are not available on all PBXs. For example, although the TSERVer
supports predictive dialing, many PBXs do not. Therefore, when you begin programming you
will need to decide which specific PBX you will work with. The alternative is to decide on a
smaller set of basic TSERVer functions to implement, most likely available from all PBXs.
Every PBX driver will come with a programmer's manual describing which TSERVer function
calls are available and implemented by their specific PBX driver.
Currently, the TSAPI supports two platforms: Windows and server NLMs. Applications
written for either of these platforms can make TSAPI requests from the TSERVer. In the future
other platforms will be supported.
TSAPI provides many services including making a call from one device (typically a
telephone) to another; putting calls on hold; transferring calls to another device; making
conference calls; and hanging up or clearing a call. Other services include advanced features such
as predictive dialing.
The NetWare Telephony Services SDK includes a sample application using many of the
basic call control features. For instance, the included rolodex-type program (TSCALL.EXE) lets
you click on a name and push a "dial" button to connect your phone with theirs.
From there, the ideas are up to you! You could write applications for a software controlled
"hunt group" for sales people or a call control center. An administrative assistant may even use
your yet-to-be-written program to conference with several members of your department. Most of
the basic features and some of the advanced features of phone systems have already been
implemented, and more changes are scheduled for the future.
SDK Debugging Tools
The SDK also includes debugging tools to help developers test their applications and to help
determine where bugs lie when TSAPI calls don't appear to be working. For developers who
don't have access to a PBX or who wish to do their application testing away from a production
environment PBX, a PBX simulator can emulate a physical PBX. No PBX is physically
connected to the TSERVer running the simulator. TSERVer simply acts as if it were a PBX and
keeps track of information on "fake" phones appearing to be available to a telephony application.
Another debugging tool is CSTASPY, which can track all incoming and outgoing telephony
messages as they occur. When something doesn't appear to be working as desired, check this log
to see if the events that actually occurred are the same as the events you desired.
If you need developer support, call 1-800-NETWARE. In this and future issues of Bullets,
read "TeleTips." Look for telephony articles in future Developer Notes as well as our fax server.
If you have questions or comments feel free to leave them with us. As you begin telephony
coding, remember Novell's Developer Support department will help you get your cutting-edge
programs to the market, and we're always open to suggestions and comments to make our
product more useful to you.
Developing in the UnixWare Environment
Since the release of UnixWare 1.1 UnixWare has been increasingly used as an application
server. As a result, many applications are written for and ported to UnixWare. Many existing
UNIX applications were designed to operate on USL UNIX SVR4.2, a predecessor of UnixWare.
These applications require very little porting effort to make them work with UnixWare.
However, with many other variants of UNIX available in the marketplace, developers require
special consideration porting applications from these systems.
The Novell UnixWare Developer Support group has found that many UNIX developers
encounter common problems. Novell intends to help UnixWare developers get going in the right
direction by covering various aspects of the UnixWare development environment, common
development problems and possible solutions.
To develop on UnixWare, you need (in addition to either a Novell UnixWare Application
Server or UnixWare Personal Edition) the Novell UnixWare Software Developers Kit version
1.1. The SDK has everything you need to develop Motif GUI applications, Windowing Korn
Shell (wksh) applications, device drivers, networking applications and character-based
applications. The SDK also includes online documentation, a Pentium(TM) C compiler, an
enhanced debugger and sample source of drivers and applications.
Installing UnixWare
The first thing you will notice when you open the Novell UnixWare SDK "Red Box" is
the apparent lack of documentation. To lower the cost of the Novell UnixWare SDK to US $95
Novell replaced printed documentation with online documentation available through the
Fingertip Librarian. If you prefer, you can purchase printed documentation separately. To open
the online documentation you must install the "guides" package. Once "guides" is installed start
up the Fingertip Librarian to produce a list of all available documentation. For C developers
Novell highly recommends that you read the "Programming in Standard C" guide which contains
the information necessary to use the C compiler and the enhanced debugger.
After installing the UnixWare SDK and reading the online documentation system, you
should consult the sample source. It is easier to start from a sample application or driver than to
start development from scratch. Sample source is available in several directories, although the
primary directory for sample source is the /usr/src directory. Two subdirectories are under
/usr/src: the ihvsrc directory, containing sample device drivers; and the isvsrc directory,
containing a sample OpenLook GUI application. For Motif GUI sample applications look into
the /usr/X/lib/ motifdemos directory and for Windowing Korn Shell samples look into the
/usr/X/lib/wksh directory.
Compiling Sample Motif Applications
If you want to compile sample Motif applications, change to one of the sample directories.
For this example we will change to the directory of /usr/X/lib/motifdemos/hellomotif. This
directory should contain the files in Figure 2.
To run the "make" command to build the hellomotif binary, you need a "Makefile." To
convert the Imakefile into a Makefile, run the /usr/X/lib/config/xmkmf in Figure 3. Executing the
ls-l command will show the resulting Makefile (see Figure 4).
Now you can execute the "make" command and get the results in Figure 5. The hellomotif
Motif application should now be successfully compiled.
Library Search Functions
During the process of compiling an application for UnixWare, developers often run into
problems with "Undefined Symbols." During the linking phase of compiling a C program, ID
consult system libraries to resolve function references. If a library has not been specified but a
function in that library is referenced, then the error stating that there are "Undefined Symbols"
will result. To examine the contents of libraries use the nm command. This command has the
output in Figure 6 on page 4 which you can incorporate into a simple shell script such as
searchlib to provide a general library search function (see Figure 7 on page 4). To determine
where a symbol (bind) is defined:
$ searchlib bind
/usr/lib/libsocket.a:0x000000c0 T bind
/usr/lib/libsocket.so:0x00008050T bind
The output of the nm command will often be a list of several library definitions. Here,
we see that bind is defined in the static libsocket.a and the shared object library (dynamic)
libsocket.so. The library name is the path that precedes the colon; your cc command line should
then include the entry -lsocket to include the socket library.
Debugging Applications
Often during the development process, you need tools to identify and eliminate bugs. Use
the enhanced debugger "debug" in most situations to debug applications. For device drivers, the
kernel debugger kdb is provided to track down bugs or errant panics. In addition to the
debuggers, the command truss enables you to watch the execution of any application and
examine the system calls used. A sample output is shown in Figure 8 on page 4.
Compiling Large Binaries
Another common problem encountered by developers of large applications or libraries is a
memory error from the linker (see Figure 9 on page 5). This error often occurs because each user
in the system has several per-process memory constraints and the linking process is exceeding
the constraints. You can easily correct the problem by increasing several kernel tunable
parameters. To increase file limit size (equivalent to ulimit):
SFSZLIM: Soft file size limit
HFSZLIM: Hard file size limit
To increase user data (process heap and brk(2)) area:
SDATLIM: Soft data limit
HDATLIM: Hard data limit
To increase user stack (stack segment) area:
SSTKLIM: Soft stack limit
HSTKLIM: Hard stack limit
To increase address space (brk(2) area) for the process:
SVMMLIM: Soft Virtual Memory limit
HVMMLIM: Hard Virtual Memory limit
Use the ulimit-a command to view the current settings of these parameters. To change
the settings of these parameters, login or su to root and use the idtune command (using SFSZLIM
as an example):
# cd /etc/conf/bin
# ./idtune SFSZLIM 0x7FFFFFFF
This idtune command line changes SFSZLIM to the unlimited setting. In addition, you
may specify a lower value than this if you do not want it set to unlimited. View each tunable
parameter's range of acceptable values by using the idtune -g command (using SFSZLIM as an
example) in Figure 10 on page 5.
The first value is the current setting, the second is the default setting, the third is the
minimum value and the last is the maximum value.
After you have changed all tunable parameters, you need to rebuild the kernel and shut down
the system:
# ./idbuild -B
# cd / ; shutdown -g0 -y
After the system has come back up, check the new settings with the ulimit -a command.
If all tunables were tuned to unlimited, you should see the results in Figure 11.
This overview of the UnixWare development environment and the frequently-encountered
problems and their solutions should give you a good start developing for UnixWare. Although
you will undoubtedly encounter your own problems, we hope an understanding of the available
tools and problems of other developers will be of great assistance in the development process.
Figure 2: Changing to the sample directory
$ ls -l
total 50
-r--r--r-- 1 root other 1036 May 20 1993 Imakefile
-r--r--r-- 1 root other 4020 May 20 1993 hellomotif.c
-r--r--r-- 1 root other 1119 May 20 1993 hellomotif.uil
$
Figure 3: Convert the Imakefile into a Makefile
$ /usr/X/lib/config/xmkmf
imake -DUseInstalled -I/usr/X/lib/config
Figure 4: The resulting Makefile
$ ls -l
total 50
-r--r--r-- 1 root other 1036 May 20 1993 Imakefile
-rw-r--r-- 1 darrend other 17327 Aug 3 09:26 Makefile
-r--r--r-- 1 root other 4020 May 20 1993 hellomotif.c
-r--r--r-- 1 root other 1119 May 20 1993 hellomotif.uil
$
Figure 5: Successful results of executing the "make" command
$ make
/bin/rm -f hellomotif.o
cc -c -O -Xa -I. -I/usr/X/X11 -I/usr/X/X11 -I///usr/X/
include -I///usr/X/include/X11 -I/usr/include -I//usr/X/include
-I. -DSVR4 -DSYSV386 -DI18N -DFUNCPROTO=15 -DNARROWPROTO
-DLIBDIR=\"/usr/X/lib\" -DDESTDIR=\"/usr/X\" hellomotif.c
/bin/rm -f hellomotif
cc -o hellomotif hellomotif.o -O -Xa -T 0x8300000
-L//usr/X/lib /usr/X/lib/libMrm.so /usr/X/lib/libXm.so -lXt
-lXext -lX11 -lgen -lnsl -ldl -lsocket -z nodefs
$
Figure 6: Examining the contents of the libraries
$ nm /usr/lib/libc*
Symbols from /usr/lib/libc.so.1:
[Index] Value Size Type Bind Other Shndx Name
...
[1600] | 209428| 4|OBJT |GLOB |0 |12 |_daylight
[1601] | 132435| 0|FUNC |WEAK |0 |8 |execve
[1602] | 176976| 88|FUNC |WEAK |0 |8 |unlockpt
[1603] | 155120| 128|FUNC |GLOB |0 |8 |vfprintf
[1604] | 129200| 0|FUNC |GLOB |0 |8 |_ioctl
[1605] | 133616| 328|FUNC |WEAK |0 |8 |lockf
[1606] | 192211| 0|FUNC |WEAK |0 |8 |auditevt
[1607] | 70670| 0|FUNC |GLOB |0 |8 |_read
[1608] | 132396| 0|FUNC |WEAK |0 |8 |execv
[1609] | 133508| 0|FUNC |WEAK |0 |8 |getmsg
[1610] | 156320| 480|FUNC |GLOB |0 |8 |_execvp
[1611] | 133571| 0|FUNC |WEAK |0 |8 |getrlimit
[1612] | 112784| 40|FUNC |GLOB |0 |8 |_toupper
[1613] | 132120| 0|FUNC |GLOB |0 |8 |_cerror
[1614] | 124608| 16|FUNC |GLOB |0 |8 |ferror
[1615] | 159440| 148|FUNC |WEAK |0 |8 |tsearch
[1616] | 192344| 0|FUNC |WEAK |0 |8 |lvlequal
Figure 7: Determining where a symbol is defined
#!/bin/sh
if [ $# -ne 1 ]
then
echo "Usage: searchlib function_name" >&2
exit 1
fi
# You may need to add library directories to this list.
LIBDIRS="
/usr/lib
/usr/ccs/lib
/usr/X/lib
/usr/ucblib"
for dir in $LIBDIRS
do
for lib in $dir/*.a $dir/*.so
do
if [ -r "$lib" ]
then
nm -px $lib | \
sed -n `/T \<'$1'\>/p' 2>/dev/null |
while read ans
do
echo $lib:$ans
done
fi
done
done
Figure 8: Sample output of truss command
$ truss hello
execve("./hello", 0x08047C58, 0x08047C60) argc = 1
getuid() = 30069 [ 30069 ]
getuid() = 30069 [ 30069 ]
getgid() = 1 [ 1 ]
getgid() = 1 [ 1 ]
procpriv(4, 0x00000000, 0) = 0
sysi86(SI86FPHW, 0x80035FE4, 0x800353A4, 0x8000E295) = 0x00000000
ioctl(1, TCGETA, 0x0804668A) = 0
Hello, World
write(1, " H e l l o , W o r l d".., 13) = 13
_exit(13)
$
Figure 9: Memory error from the linker
ld: libelf error: memory error: output file space elf_update
error code 1 (bu21).
Figure 10: View range of acceptable values
# ./idtune -g SFSZLIM
0x1000000 0x1000000 0x2000 0x7FFFFFFF
Figure 11: Checking the tunable parameters with ulimit-a
$ ulimit -a
time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) unlimited
coredump(blocks) 2048
nofiles(descriptors) 256
vmemory(kbytes) unlimited
$
AppWare Foundation Release
Novell announces the general release of the AppWare Foundation for six major platforms:
Macintosh, MS Windows, UnixWare, Sun/OS, Sun/Solaris and HP-UX.
The following SDKs are available:
- The AppWare Foundation for Macintosh 1.90 includes a prerelease SDK for
native support of the Power Macintosh using Metroworks compilers.
- The AppWare Foundation for MS Windows 1.90 includes a developer prerelease SDK
for support of MS Windows NT so you can develop and deploy applications on MS Windows
NT and MS Chicago when it is available.
- The AppWare Foundation for OS/2 PM 0.85 Developer Prerelease SDK.
If you're ready to move to object-oriented programming, Novell is releasing
ObjectWindows for AppWare Foundation (OW/AF) developer prerelease on the Macintosh, MS
Windows and OS/2 PM platforms.
We're also launching the Early Experience Program for OW/AF. This program will allow
you to take advantage of early releases of Novell and Borland's new cross-platform application
framework at a lower cost (no "beta site" commitment). For more information on the OW/AF
bundled SDKs or the Early Experience Program call 1-408-431-5172.
Hints for Accessing Files Quickly from the NetWare NLM SDK
Novell has come up with some APIs called Advanced Services. To access a file quickly, use the
following API calls:
- AsyncRead: this reads the file directly from the file server's cache memory (if the
file is already in cache)
- qread: low overhead read operation
- qwrite: low overhead write
Note: These files are using NetWare's disk caching and transaction tracking if active. Default
Disk caching on a 3.x server is 4k. On 4.x it is configurable, starting at 4k (8k, 16k, 32k or 64k).
This happens at install time. All files are open in normal mode.
If you want to bypass NetWare disk caching and Transaction Tracking System it enabled, Novell
does not recommend using the Direct File System (DFS) calls unless:
- Your application is doing its own caching and transaction tracking and you are
experiencing performance degradation when you have both NetWare and your application's
transaction tracking and disk caching.
- Backup applications often access large amounts of data not being accessed by other
applications. If these accesses are made through caching, the cache becomes nonrelevant for all
other accesses, and general server performance suffers for other users.
For more detailed information on the file structures and direct file system I/O, refer to
NetWare Services for NLMs, chapter 22, Direct File System services. For more information on
parameters each API needs, refer to NLM Library Reference Volume I.
Use any of the following API calls:
- DFSOpen
- DFSClose
- DFSCreate
- DFSExpandFile
- DFSFreeLimboVolumeSpace
- DFSRead: reads sectors from a file in direct file mode (sleeps until completion)
- DFSReadNoWait: reads sectors from a file in direct file mode (returns immediately after
initiation)
- DFSReturnFileMappingInformation: returns file extents, each with number of blocks and
starting file and volume block numbers
- DFSReturnVolumeMapping: Information: returns information about a volume
required for allocation
- DFSSetEndOfFile: sets the file size
- DFSsopen: opens a file in direct file mode
- DFSWrite: writes sectors into a file using DFS (sleeps until completion)
- DFSWriteNoWait: writes sectors into a file using DFS (returns immediately after
initiation)
Note: When a file is open in direct mode (DFSsopen) the server opens the file, flushes all
cache entries for the file and flags the file so that future I/Os do not use caching and TTS
functions.
Operating System I/O calls perform non-buffered I/O operations. Files opened at the
operating-system level (with open, sopen, and create functions) are opened at the stream level.
Note: These files are using NetWare's disk caching and transaction tracking if active. Default
Disk caching on a 3.x server is 4k. On 4.x it is configurable starting at 4k (8k, 16k, 32k or 64k).
This happens at install time. All files are open in normal mode.
File Engine (FE) Services are used to service non-DOS file systems such as Apple's
Appletalk Filing Protocol (AFP) and Sun Microsystem's Network File System (NFS). These
APIs can be referenced in the NLM Library Reference Volume I (FECreat, FEFlushWrite,
Fesopen and so on).
Note: These files are using NetWare's disk caching and transaction tracking if active. Default
Disk caching on a 3.x server is 4k. On 4.x it is configurable, starting at 4k (8k, 16k, 32k or 64k).
This happens at install time. All files are open in normal mode.
Stay tuned next month for some sample source.
Gotchas in Event Monitoring
Monitoring systems events can be a challenging area of NLM development. Not only do you
have a large number of events available to monitor, but you must be aware of a number of
behavior issues of both the core OS and your NLM.
You can monitor two main areas of events: system events or file system events. The two
APIs for these are RegisterForEvent and NWAddFSMonitorHook, respectively. These two
functions work in a similar manner; they take parameters that specify the event type you wish to
monitor and the routine to be invoked when that event is generated. The routine that you provide
to these event services become callback routines to the OS.
Callback routines and OS Threads
If you provide a routine as a callback routine to the system, you need to take care which
operations you call in that routine. In most instances when an event is called, your routine is
called from a OS thread. This means that any resources that your NLM provides or that CLIB
provides will be in a different context than the context in which your callback routine is being
executed. One solution is to specify the context for the execution of your routine prior to calling
any functions that use CLIB context. To do this, use the GetThreadGroupID call in the main
body of your program and store the result in a global variable (see Figure 12).
In the callback routine use something like the example in Figure 13. These operations will
ensure that your routine is in the proper context for execution. You can find more details in the
NetWare NLM Development and Tools Overview manual in the section "NLM Program Coding
Issues."
Sleeping Dogs versus Sleeping Threads
It may be said that you should let sleeping dogs lie, but the same is not always true for
your callback routines. Many times you cannot permit a callback routine to fall asleep. Since this
is a gotcha that can bite hard, you might want to get into the habit of writing your callback
routines to avoid this problem. One method that I like is to write a pair of routines for each event
that I wish to monitor.
The first routine is the actual callback routine itself. In this routine I set the thread context (as
shown above), copy any data passed to the callback routine to a global data structure, then
SignalLocalSemaphore and exit the routine. I spin off the other routine as a independent thread
somewhere in my main module. The only thing it does is WaitOnLocalSemaphore. Once the
semaphore has been signaled, this routine will take the data from the global data structure and
process it according to the needs of my NLM.
This may cause some additional work, but it makes a more consistent design and eases
implementation of event callback routines.
Notes on RegisterForEvent API
Not all events in the list for RegisterForEvent can be called in NetWare 3.x. Event types up
through event 29 (EVENT_DESTROY_PROCESS) are available to NetWare 3.x. All other
events are available in NetWare 4.0x except for EVENT_CHANGE_SECURITY and
EVENT_QUEUE_ACTION.
Figure 12: Specify the context for the execution
#include
int globalThreadGroupID;
main()
{
globalThreadGroupID = GetThreadGroupID();
...
}
Figure 13: Insuring the routine is in the proper context for execution
int oldTGID;
oldTGID = SetThreadGroupID( globalThreadGroupID );
/* Do work */
SetThreadGroupID( oldTGID );
/* always set back the thread group ID */
TeleTip #1
Recently Novell released the NetWare Telephony SDK, enabling developers to create
software to control telephone systems with supported hardware installed including a link between
a Novell NetWare file server and a telephone switchbox (PBX) with a supported driver for
NetWare. Beginning with this issue of Bullets, "TeleTips" will contain tips, tricks and answers to
common questions or issues regarding NetWare Telephony from an administrative point of view
as well as a programming point of view.
All of the TeleTips may not appear in Bullets. If you notice you are missing any (they will be
numbered consecutively, beginning with TeleTip #1) you can get them from our fax service or
from CompuServe.
Cross-Dressed diskettes
The Telephony Services SDK has two diskettes that are mislabeled. They contain correct
information, but they have each others' labels. These diskettes are TSRVDSK1 and TSRVDSK2.
Tip: When you need the diskette TSRVDSK1 insert the TSRVDSK2 diskette and
vice-versa.
TeleTip #2
Where's the Code?
Use the sample program in Figure 14 on pages 9, 10 and 11 to open a stream and make a
call. Future Telephony Services API (TSAPI) sample programs will be written to this same
coding style to make it easier to read the comments and the code. After all, we were hired as
engineers, not literature majors.
Tip: Use the code in Figure 14 as a template for making telephony programs. It
contains the framework to which other function calls can be added.
Figure 14: Sample telephony program
/**************************************************
** Include headers, macros, function prototypes, etc.
/*-------------------------------------------------
** ANSI
*/
#include
#include
/*-------------------------------------------------
** Windows
*/
#include
/*-------------------------------------------------
** Telephony
*/
#include
#include
/**************************************************
** This function is the entire program; it is very
** simple.
** Prompt user for input, open a stream, make a
** call and close the stream.
*/
void main(void)
{
/*--------------------------------------------------
The following are defined for the first call, acsOpenStream
*/
ACSHandle_t acsHandle;
InvokeIDType_t invokeIDType;
InvokeID_t invokeID;
StreamType_t streamType;
ServerID_t serverID;
LoginID_t loginID;
Passwd_t passwd;
AppName_t applicationName;
Level_t acsLevelReq;
Version_t apiVer;
unsigned short sendQSize;
unsigned short sendExtraBufs;
unsigned short recvQSize;
unsigned short recvExtraBufs;
PrivateData_t *privateData;
RetCode_t rCode;
/*---------------------------------------------------
**The following are additional variables necessary for
**acsGetEventBlock
*/
CSTAEvent_t eventBuffer;
unsigned short eventBufferSize;
unsigned short numEvents;
/*-------------------------------------------------
**The following are for the cstaMakeCall
*/
DeviceID_t caller,callee;
/*-------------------------------------------------
**Miscellaneous variables
*/
short done=0;
/*-------------------------------------------------
**Setup parameters for call to open stream. Also prompt user for
**input.
*/
invokeIDType=LIB_GEN_ID;
invokeID=0; /*don't need it, but set to zero anyway*/
streamType=ST_CSTA; /*want to use csta functions*/
strcpy(serverID,"ATT#G3_SWITCH#CSTA#PRV-NMS");
printf("\nEnter your user name:");
scanf("%s",loginID);
printf("\nEnter your password:");
scanf("%s",passwd);
printf("\nEnter your extension:");
scanf("%s",caller);
printf("\nEnter the extension you want to call:");
scanf("%s",callee);
strcpy(applicationName,"Simple App");
acsLevelReq=ACS_LEVEL1;
strcpy(apiVer,CSTA_API_VERSION);
sendQSize=0; /*default size queue*/
sendExtraBufs=0; /*use default number*/
recvQSize=0; /*use default size*/
recvExtraBufs=0; /*use default number*/
privateData=NULL; /*no private data*/
/*-------------------------------------------------
**Open the stream with above parameters
*/
rCode=acsOpenStream(&acsHandle,invokeIDType,invokeID,streamType,
serverID,loginID,passwd,applicationName,acsLevelReq,
apiVer,sendQSize,sendExtraBufs,recvQSiz,recvExtraBufs,
privateData);
if (rCode < 0)
{
printf("acsOpenStream failure...");
return;
}
else
{
printf("acsOpenStream success\n");
invokeID=rCode;
}
/*-------------------------------------------------
**Block until the confirmation has been received that the stream
**was successfully opened. Just because NetWare returned the
**function code doesn't mean the stream has been opened yet.
*/
eventBufferSize=sizeof(CSTAEvent_t);
rCode=acsGetEventBlock(acsHandle,&eventBuffer,&eventBufferSize,
privateData,&numEvents);
if(rCode==ACSPOSITIVE_ACK)
{
if(eventBuffer.eventHeader.eventType == ACS_OPEN_STREAM_CONF)
{
printf("ACS_OPEN_STREAM_CONF message has been received\n");
}
else
{
printf("event type is incorrect...");
return;
}
}
else
{
printf("acsGetEventBlock failure...");
return;
}
/*-------------------------------------------------
**Now that the stream has been successfully opened,go ahead and
**issue the make call function.
*/
rCode=cstaMakeCall(acsHandle,invokeID,caller,callee,
privateData);
/*--------------------------------------------------
**Now we need to poll for events until a confirmation has been
**received that the PBX has been able to make the call. Note
**that if something is invalid, the program will enter an
**infinite loop, as this simple program just sits and waits
**until a confirmation returns that is successful.
*/
while (!done)
{
rCode=acsGetEventPoll(acsHandle,&eventBuffer,&eventBufferSize,
privateData,&numEvents);
if(rCode==ACSPOSITIVE_ACK)
{
if(eventBuffer.eventHeader.eventType == CSTA_MAKE_CALL_CONF)
{
printf("CSTA_MAKE_CALL_CONF message has been received\n");
done=1;
}
else
{
printf("event type is incorrect...");
}
}
}
/*-------------------------------------------------
**All done! Time to close the stream now.
*/
rCode=acsCloseStream(acsHandle,invokeID,privateData);
if (rCode < 0)
{
printf("acsCloseStream failure...");
return;
}
else
{
printf("acsCloseStream success\n");
}
return;
}
TeleTip #3
Don't Walk Through a Closed Door
It seems simple enough, doesn't it? It's the same concept when programming for NetWare
Telephony: you have to open the stream for Telephony to function. An acsStream is the most
crucial piece of information to a telephony program. It is your door to the Telephony Server
(TSERVer). Almost every function provided by the Telephony Services API (TSAPI--I say
"tee-sappy") requires that you have an open stream, passed as a parameter to the function.
To open the stream, a program calls acsOpenStream(), which is passed several parameters
regarding the type of stream the program wishes to open. The TSERVer returns a completion
code to your program. However, this doesn't mean that the stream has been successfully opened.
Two components are involved in TSAPI programming.
The first component is the TSERVer, which returns the completion code as a return value in
TSAPI function calls. This code tells whether or not the TSERVer was able to accept your
function call.
The second component of TSAPI is the telephone switch box (PBX) driver. It handles many
of the API requests. To know when the PBX driver has performed an action, Events are passed to
a program. These events come in many shapes and sizes (I suggest printing out the .H header
files to become familiar with the overwhelming amount of structures) and can be either
"solicited" or "unsolicited," depending on whether or not your program specifically requested
them.
Receiving Confirmation Events
The most important events for us at this time are ConfirmationEvents. They tell the
program if the service requested by the function call was completed correctly. Our program
doesn't know when to expect these events to come back. They could return immediately, or the
PBX may have to do some processing and return to our program shortly.
As a human, I don't notice a difference in the delay, but I guess my computers are more
picky regarding "immediate" and "delay." Because I have to cater to my computer when I
program, I guess it is important to consider the confirmation events receiving time. For example,
I may have one function call that needs to be complete before others can be made. In this case
my program needs to pause and wait to receive the confirmation event from that function call.
In future Teletips we will discuss four methods of receiving confirmation. Look for it on the
fax server, CompuServe, future issues of Bullets or call 1-800-NETWARE for technical support.
Now that you have a little background about events, let's think about the acsOpenStream
function call. If the stream has to be open before any other TSAPI calls can be made, but you
don't know how long it will take to receive the confirmation event, how long should you pause
your program before attempting to make other calls? If you use the acsGetEventBlock() function,
your program will pause until a confirmation event is received. Since the first event that can be
received is guaranteed to be an openStream confirmation event (type
ACS_OPEN_STREAM_CONF), your program will pause until the stream has been opened. The
only other type of event that can be received at this point in the program will indicate that the
stream was not able to be opened, and your program cannot proceed to make other TSAPI calls.
Tip: By "blocking" or using the acsGetEventBlock() function after you try to open
a stream with acsOpenStream, you can make sure your door is open before trying to walk
through it.
Teletip #4
Did You Check All the Books?
As I was writing my first program to do conference calls, I found a call function listed in
the TSAPI programming guide, cstaMakeConsultationCall(), which would put a call that has
already been connected on hold and then make the second call. This is the equivalent of first
using cstaHoldCall(), and then cstaMakeCall(). I thought I was set! So I got my program written,
compiling and running. But the events coming back weren't correct for doing the
cstaMakeConsultationCall(). In fact, when I would run the program, nine times out of ten the
machine would lock up--not cool!
After a little time on my part, I decided to look in the DEFINITY System Programmer's
Guide, where I probably should have started in the first place. I couldn't find the
csatMakeConsultationCall() function documented anywhere. It turns out that the driver doesn't
support this call. So I had to program the equivalent of the cstaMakeConsultationCall() myself,
first placing the already connected call on hold, and then making a second call.
The bottom line is this: if I would have checked the DEFINITY System Programmer's Guide
first, I would have saved myself a lot of time.
Tip: Though the TSAPI programmer's guide lists the functions provided by
TSERVer, it is important to use the programmer's guide for your specific PBX as the reference of
what is supported by your driver. Just because TSAPI provides it doesn't mean the service is
available through your driver.
© 1994 Novell, Inc. All rights reserved. Novell, the N design, NetWare, DR DOS,
Btrieve, XQL and LANalyzer are registered trademarks; LAN WorkShop, NetWare SFT III,
NetWare Loadable Module, NLM, Global MHS, NetWare MHS, NetWare System Calls for
DOS, NetWare Runtime, NetWare SQL, NetWare Btrieve, Report Executive, NetWare
Asynchronous Services Interface (NASI), NetWare Management System, Xtrieve PLUS, Novell
Labs, UnixWare, AppWare, AppWare Foundation, ALM, Visual AppBuilder, IPX, and MacIPX
are trademarks; and NetWire and Professional Developers' Program are service marks of Novell,
Inc. IBM and OS/2 are registered trademarks, and NetBIOS and SAA are trademarks of
International Business Machines Corporation. Microsoft is a registered trademark and Windows
and Visual Basic are trademarks of Microsoft Corporation. Macintosh is a registered trademark
of Apple Computer, Inc. CompuServe is a registered trademark of CompuServe Corporation.
NFS is a registered trademark of Sun Microsystems, Inc. UNIX is a trademark of UNIX Systems
Laboratories, Inc. in the USA and other countries. UNIX Systems Laboratories is a
wholly-owned subsidiary of Novell, Inc. WATCOM is a registered trademarks of WATCOM
Systems, Inc. Novell, Inc. makes no representations or warranties with respect to any NetWare
software and specifically disclaims any express or implied warranties of merchantability, title or
fitness for a particular purpose. Distribution of any NetWare software is forbidden without the
express written consent of Novell, Inc. Further, Novell reserves the right to discontinue
distribution of any NetWare software. Novell is not responsible for lost profits or revenue, loss of
use of the software, loss of data, costs of re-creating lost data, the cost of any substitute
equipment or program or claims by any party other than you. Novell strongly recommends you
make a backup before any software is installed. Technical support for this software may be
provided at the discretion of Novell.
How to Become One of Our Developers
Developing computing systems is a complex, time-consuming and expensive task. Novell
understands this and is committed to its developer partners. The Novell Professional Developers'
Program allows you, our developer, to access our broad base of 40 million NetWare users to
develop and market your products.
This program is designed for a wide range of developers who design and create
commercially available solutions. This includes commercial developers, called Independent
Software Vendors (ISVs), and vertical application developers who create applications for
specialized markets such as manufacturing, medicine and law.
Key Features
Members of the Novell Professional Developers' Program receive the following benefits.
- Co-Marketing Support
Members can participate in the YES Program, which offers a variety of co-marketing
opportunities as well as ongoing information about Novell's direction. The ultimate goal of the
YES Program is to make it easy for customers to identify and purchase products that are
optimized for Novell platforms.
- Technical Support
To obtain product information and technical support, phone 1-800-RED-WORD
(1-800-733-9673) or 1-801-429-5281.
- Skills Transfer
Members may participate in the Skills Transfer Workshops conducted by a Novell
specialist. The workshops offer cutting-edge training on solution design, development and
implementation. Members may also attend Novell Compass Special Interest Groups, where they
have the chance to review products and provide feedback directly to Novell development teams.
- Project/Opportunity Services
Members have access to Novell expertise through the developer forums on CompuServe.
These forums address developer issues including technical information and support for Novell
products and development tools.
- Information Services
As a developer, you receive Novell Developer Notes, a publication targeted at network
software developers. Other publications are also available: Bullets, a monthly technical journal;
Appnotes (subscription only), a technical journal for network design; and the annual Developer
Guide to Programs, Products, and Services. Members also get access to Novell's
NDEVSUP CompuServe forum_an electronic meeting place where developers can exchange
information with each other and with Novell staff members.
- No Program Fees
Membership in this program is free of charge and open to all developers.
If you would like further information about the Professional Developers' Program or would like
to apply for membership, please phone 1-800-RED-WORD (1-800-733-9673) or
1-801-429-5281. If you would like to order Novell development tools, please call
1-800-RED-WORD.
You may also contact the program administrator by E-mail at the following address:
devprog@novell.com.
Boy--if one thing's certain in the computer industry, it's change (sorry about the cliche).
Organizations change shape, new names appear and through it all we hope that we don't break
what works while improving what doesn't work so well.
Why isn't Mad Poarch writing this column? Novell has experienced some significant
changes over the past several months. First, we have completed the spin-off of the Btrieve and
NetWare SQL technologies to a newly formed company, Btrieve Technologies, Inc. in Austin,
Texas. Quite a few of Novell's Austin-based employees have become part of the BTI Developer
Support organization including the former Director of Developer Support, Mad Poarch. Novell
wishes them the very best!
We have relocated the Developer Support function as well as Developer Programs from
Austin, Texas to Provo, Utah. As the new head of the Developer Support group, I want to share a
few of my thoughts about our new organization and what you can expect of us in the future.
Of course, the BTI spin-off has not only affected Novell internally, but has also had an effect
on our ability to be responsive to you, our development partner. During the past several months
we have re-established the expertise lost in the spin-off. We are now prepared to support users of
our SDKs and toolkits, including the new Telephony technology, AppWare Foundation,
UnixWare and of course our traditional client and server APIs.
BTI is now the sole source of support for Btrieve products and development tools, Xtrieve
and SQL. Call BTI at 1-800-BTRIEVE for customer support of these database products. With the
formation of BTI and the completed transfer of the Btrieve technologies to BTI, Novell's
Developer Support organization is now concentrating on supporting the Novell APIs as delivered
in SDK form. We have many ways you can contact us, including a newly enabled e-mail
mechanism:
Voice: 1-800-NETWARE
(or 1-801-429-5588)
CompuServe/NetWire: GONetWire, Developer Support Forum
-or- Post directly to
Novell DevSup @ 76701,171
Fax: 1-801-429-2990
E-mail: DEVSUP@NOVELL (MHS)
DevSup@Novell.com (SMTP)
FaxBack Info: 1-800-NETWARE
(or 1-801-429-5588)
1-800-RED-WORD
Our support organization is also the designated point of contact for the assignment and
registration of various software IDs used by our developers. These software IDs include Server
Type numbers, IPX socket IDs, VLM IDs, Directory Services Schema Classes and Objects. To
register call our administrator at 1-801-429-3101.
You will notice that this issue is number 4 even though it is the September issue. With the
Austin-to-Provo transition, we saw four months pass without producing an issue. Now that the
transition is complete, you can expect to see regular, monthly publication of future issues of
Bullets.
Many of us are new to this effort, but you will find that we're excited to work with you. We
believe our opportunity for growth with you is vast and encouraging. In addition, we will be a
strong and supportive advocate for your needs to the rest of the Novell organization.
Jared Blaser
Director
Developer Support/Services
Available Novell Developer Education Courses
Novell Developer Education offers several courses for developers who use Novell's
development tools.
930 - Developing NetWare Loadable Modules (NLMs)
940 - NetWare Programming: Basic Services
941 - Directory Services
945 - NetWare Programming: Protocol Support
950 - Visual AppBuilder
954 - -ALM Development
958 - The AppWare Foundation
To obtain information on pricing, location, scheduling and course content for classes
held in the US, call 1-800-233-3382, 1-801-429-5508 or 1-800-NETWARE. For information on
classes outside of the US, contact your local Novell office.
Developer Support
Developers in the U.S. and Canada may contact Novell Developer Support via telephone, fax,
BBS or electronic mail via CompuServe, MHS or the Internet.
Voice
For both presales and postsales support, call Novell Developer Support between 8:00 a.m. and
5:00 p.m. Mountain Time at 1-801-429-5588. Many calls to Novell Developer Support are
passed to a software support engineer immediately. Calls to Novell Developer Support generally
will be acknowledged or answered within four hours.
Fax
If you prefer, you may contact Novell Developer Support via fax at 1-801-429-2990. Faxed
questions are acknowledged or answered within 24 hours.
Developer BBS
If you do not have access to either CompuServe or the Internet, send test cases to our BBS. Set
your communication software to N-8-1 and call 1-801-429-5836.
E-mail: CompuServe
Post your messages in the appropriate section addressed to Novell at 76701,171. These messages
will receive a response within 24 hours.
E-mail: MHS
You may direct your questions and comments to Novell Developer Support via Novell's Message
Handling Service E-mail facility. Address your messages to devsup@novell. These messages
will receive a response within 24 hours.
E-mail: Internet (SMTP)
An alternative method of contacting Novell Developer Support is through the Internet E-mail
system. Send your messages to devsup@novell.com. These messages will receive a response
within 24 hours.
NetWire on CompuServe
Novell's NetWire forum is open to all registered CompuServe subscribers. Through the
NDEVSUP forum, professional developers writing applications with Novell development tools
can gain access to information specific to Novell development. Support, patches, periodicals and
product information, as well as information on all of the programs and services provided for
Novell developers are accessible through this forum. Post your messages in the appropriate
section addressed to Novell at 76701,171. Technical questions will be acknowledged or
answered by Novell Developer Support within 24 hours.
Novell Products and SDKs
Novell products on the "Currently Shipping Developer Products" list (see page 15 of this
issue), including the Red Box Products, are available to Novell Professional Developer's
Program members. Call 1-800-RED-WORD (1-800-733-9673) or 1-303-894-4135 to order these
products or to receive additional information. To order other Red Box Products not listed,
contact your local Novell office or Novell Authorized Reseller.
Novell Labs
For information on Novell Labs development tools, education classes and product certification,
in the U.S. and Canada call 1-800-453-1267 ext. 5544 or 1-801-429-5544, or call your local
Novell office (see back cover of this issue).
Novell Developer Relations
Novell Professional Developers or those wishing to become members may contact Novell
Developer Relations via telephone, fax, or electronic mail via Compuserve, MHS or the Internet.
Voice
For general information or questions on Novell Developer Relations programs, in the U.S.
or Canada call 1-800-RED-WORD (1-800-733-9673). All others call 1-801-429-5281.
Fax
If you prefer, you may contact Novell Developer Relations via fax at 1-801-429-7207.
NetWire on CompuServe
Novell's NetWire forum is open to all registered Compuserve subscribers. Through the
NDEVREL forum, Novell Professional Developer's Program-related issues or general questions
may be posted. Through the NDEVINFO forum, customers who do not have products may post
pre-sales product information questions on all Novell SDKs.
E-mail: MHS or Internet (SMTP)
You may direct your questions and comments to Novell Developer Relations via Novell's
Message Handling Service E-mail facility. Address your messages to devprog@novell.com. Use
the same address when going through the Internet E-mail system.
|