MultiX	Introduction	Chapter 1

Introduction

MultiX is network software that enables applications on a network or on the 
same computer to exchange information transparently, independently of  the 
hardware platform or operating system used to run the applications and 
independently of the communications protocol used.

Who Should Use MultiX? 
MultiX is for organizations that operate networks that incorporate more 
than one hardware platform, operating system, communications medium or 
protocol.

Getting to Know MultiX 
MultiX approaches networking from a unique perspective, called process-
oriented networking.  Understanding  process-oriented networking will help 
you get the most benefit from MultiX.

MultiX	- Process-oriented Network Software
Unlike other network software packages which provide network services for 
computers and peripherals, MultiX provides network services for processes.  
MultiX is a processes network, rather than a computer network.

Why MultiX is Process-oriented 
Thanks to its process orientation, MultiX delivers unparalleled portability 
and transparency between applications operating under one or more 
operating systems, hardware platforms and communications protocols.

How Developers Use MultiX 
The application developer uses MultiX by writing a MultiX event handler 
for each process in the application.  The MultiX network software manages 
message exchange using the event handlers written by the application 
developer.

In a network connecting many operating systems and communications 
protocols, developers using traditional network software need to write many 
lines of code for each operating system and communications protocol.  
Under MultiX, a short series of commands is sufficient no matter how 
complex the network.

MultiX Simplifies System Development 
MultiX allows you to implement and modify your network without affecting 
how applications on your network share data or computing resources.  
Under MultiX, you can freely mix and match hardware platforms, 
communications hardware, link level protocols (if needed), transport level 
protocols, queue and message management, and application 
synchronization and flow control methods.

Example 
Under traditional network software, if NetBIOS support was added to 
TCP/IP, all applications using TCP/IP sockets would have to be partially or 
totally rewritten because of the difference between TCP/IP and NetBIOS.  
Under MultiX, applications will be able to use the new network features 
with no development effort at all.


Developing Open, Distributed Applications 
MultiX speeds and simplifies development of open, distributed applications 
that are relatively resilient to changes in the network environment. 
When developing distributed applications using the MultiX development 
tool kit, MultiX handles all Inter Process Communications (IPC) and frees 
the developer from an array of problems, including incompatibilities 
between operating systems, communication protocols and message flow 
control.

Transparently Supports Wide Array of Software and Hardware
After implementing MultiX, you can freely add hardware and software to 
your network.  New applications will be able to share resources with 
existing applications, with no need for special support.  MultiX supports a 
wide array of software and hardware including :

Oprating Systems :
MS-DOS, MS-WINDOWS, MS-WINDOWS NT, OS/2 2.x, SCO UNIX.

Transport Protocols:
OS/2: Named Pipes, Tcp/Ip, NetBios, Async , X25.
UNIX: Tcp/Ip, Async, X25, Ipx/Spx .
DOS: NetBios, Async, Ipx/Spx.
WINDOWS: NetBIOS, Async, Tcp/Ip (WINSOCK).
WINDOWS NT: NetBios, Async, Ipx/Spx, TcpIp,Named Pipes.

System Development Under MultiX - Core Issues

Identifying Processes Using a Unique ID

After a process is assigned a unique MultiX ID, it can be moved to any 
computer in the network without affecting any other process in the network. 
Coding for Portability 
MultiX hides all specific operating system services from the developer, 
making application code portable to any other platform supported by 
MultiX.  MultiX supplies timers and memory management routines which 
typically are operating system dependent.

No Need to Code for Specific Transport Protocols 
Since MultiX is built as a layered system, all interactions with lower layer 
protocols are hidden from the application.  The application developer is 
provided with one set of Application Programming Interfaces (APIs) 
regardless of the protocol being used. 
In non-DOS environments, MultiX does not interact directly with the 
hardware but rather with operating system services and with Transport 
Layer providers.  Operating systems and transport protocols are transparent 
to most of MultiX.   In DOS environments, where there is no support for 
asynchronous lines, MultiX interacts directly with the hardware. 


What MultiX Does

MultiX Versus Traditional Network Software 
If traditional network software sorts and moves messages much like old-
fashioned telephone systems , sending messages with operator (or
developer) assistance , MultiX sorts and moves messages much like a
person-to-person phone call, with no developer assistance required. 
MultiX enables a process, wherever it is located to communicate with 
another process in any other location.  Where traditional network software 
routes communication from computer A to computer B (refer to Figures 1.1 
and 1.2), MultiX routes communications from computer A, process 4 to 
computer B, process 3 (refer to Figures 1.3 and 1.4). 


  
Figure 1.1  A Traditional  Network 
 
  
Figure 1.2  Conventional Network Software 
 
  
Figure  1.3  A MultiX Network 
  
Figure	1.4  MultiX Communication

Client/Server Under MultiX 
MultiX supports client and server connections.  In server connections 
MultiX "listens" to incoming calls.  In client connections MultiX initiates 
contact. 
Regardless of the transport protocols, MultiX can implement both 
connection types on the same link.  MultiX-based networks do not require a 
strict division between clients and servers.  In fact, each process may serve 
as client and server over multiple active links (of the same or different 
types) simultaneously.

Network Features

Session Management 
When any two processes are connected by a MultiX Session, they may 
communicate.  Any process may have an active MultiX Session with one or 
more processes at any time.

Transport Services 
Once a session exists between two processes, the processes may transfer 
data.  The MultiX API provides reliable message transfer for large messages 
or files, regardless of the network protocol or operating system.  MultiX 
provides reliable transfer even across sessions, meaning that no data is lost 
in case of link failure.

Rerouting Services 
MultiX automatically reroutes communications for optimal throughput.  If 
there is no direct link between processes, MultiX transparently reroutes 
sessions and messages between the processes.  In fact, two processes may 
exchange information through a third process without interfering with the 
third process and without requiring special programming to the 
communicating processes. 
  
Figure 1.5  Dynamic Load Balancing 
 
Fault Tolerance and Dynamic Load Balancing 
MultiX can connect two processes by more than one physical link, using all 
links simultaneously to maximize throughput. 
Rather than assigning each process statically to a communications line, 
MultiX operates with dynamic load balancing.  By using dynamic load 
balancing (see Figure 1.5) MultiX ensures that message traffic flows 
through any available link.  In the event of link failure, data continues to 
flow on remaining links.  MultiX ceases to transmit only when all links fail. 
Where a direct link exists between two processes, MultiX transmits 
messages via the direct link.  If the direct link fails, MultiX resorts to 
indirect links.  Recovery from link and even controller failure is transparent 
to the process.

Gateway Capability 
MultiX allows you to designate specific processes as "gateways".  Gateway 
processes connect processes to other processes linked to the gateway 
process. 
MultiX can also act as a protocol converter, allowing  a process connected 
to a gateway using one type of link (such as a dial- up asynchronous line) to 
communicate with another process connected to the gateway using another 
type of link (such as TCP/Ip).

Preemptive Prioritized Message Queues 
MultiX allows you to assign different priorities to different messages issued 
by different applications.  MultiX manages transmission queues on a 
priority basis, rather than on a first in first out basis. 
MultiX messages are preemptive.  This means that when a higher priority 
message arrives at a MultiX transmission queue, MultiX divides the 
message into blocks and transmits the blocks before any block of lower 
priority messages.  If the higher priority message interrupts transmission of 
blocks of a lower priority message, MultiX resumes transmitting the lower 
priority message after transmitting all higher priority messages.

------------------------------------------------------------------------------

MultiX	MultiX Objects	Chapter 2

MultiX Objects

MultiX Object Oriented Programming

MultiX is an object oriented programmer's tool kit.  Each MultiX object is 
self-contained, having all of the logic it needs in order to do its job.  
Because MultiX is an object oriented tool kit, the MultiX programmer need 
not concern himself with the task to be performed, which is handled by the 
object itself, but rather with the object, and what MultiX does with the 
object. 
MultiX recognizes five objects: links, processes, messages, events and 
timers.

*	MultiX Links  MultiX handles interfacing with existing 
communications protocols, controlling links and routing.  After 
defining the link parameters, all communications functions are 
completely transparent to the programmer except for opening and 
closing links, and checking link status. 
As MultiX releases support for new communication protocols, you need 
not change your MultiX code servicing the network.  Just install the 
updated version of MultiX.

*	MultiX Processes  MultiX processes are objects exchanging 
information using MultiX.  After defining the process parameters, all 
message exchange functions are completely transparent to the 
programmer except for initiating communication with the process.  
MultiX is indifferent to the function performed by the process.

*	MultiX Messages  MultiX handles message blocking and routing.  
All message blocking and routing functions are completely transparent 
to the programmer.  The programmer only needs to instruct the 
application to create and send the message.  MultiX is indifferent to 
message content.

*	MultiX Events  MultiX applications are event-driven.  Application 
events are the main concern of the developer.  Once the MultiX event 
handler is written for an application, the event handler deals with any 
event as it occurs.

*	MultiX Timers  MultiX timers are set by the application.

Important Note 
MultiX was developed in C, and MultiX Objects, Structures, Types, and 
Application Programming Interface (API) are in C.  This manual is directed 
primarily at C programmers. 


MultiX Links 
MultiX Links are the physical communications links between MultiX 
applications (refer to Figure 2.2). 
  
Figure	2.1

Defining and Using Links 
A link can be an asynchronous port ("COMx") on a DOS-based PC, or 
"/dev/ttyxx" on a UNIX machine.  It can be a named pipe on OS/2 or a 
socket address on a TCP/IP network.  Each link is defined in MultiX by the 
parameters specified in the link description.  Once the link parameters are 
defined, the programmer need only call MdxOpenLink. 
After specifying link parameters and opening the link, MultiX assumes full 
responsibility for transmission over the link, and the programmer need not 
refer to the link again, except to close the link or check the link status.  
MultiX takes full responsibility for link management and link integrity. 
Every link in MultiX has a link type which must be defined.  MultiX link 
attributes are presented with the structure: TMdxLinkParams, as explained 
in Chapter 4.

When to Open a Link 
Before transferring data, the programmer must open a link using the 
MdxOpenLink call, defining the link as available for MultiX 
communication, regardless of which application is on the other side of the 
link.  MultiX and processes on one side of a link do not "know" in advance 
of opening links what processes are on the other side of a link.

Important Information! 
A MultiX process may use more than one link of any type at any time.

Links in Multitasking Systems 
On multitasking operating systems, such as UNIX and OS/2, only processes 
configured as "gateway processes" (refer to MultiX Processes in this 
chapter) need to open links, the rest of the processes access links to the 
"outside" world through the gateway.

MultiX Processes 
As opposed to a MultiX link which is always physical, a MultiX process is 
conceptual or logical.  A process can be an MS-DOS TSR, or an application 
in MS-DOS, MS-Windows, OS/2 or UNIX.  MultiX provides the 
mechanism for processes to "talk" to other processes regardless of the 
location of the process and the operating system under which it is running.

Identifying MultiX Processes 
Each MultiX-based process has a unique MultiX ID.  In order for one 
process to communicate with another process, the calling process only needs 
to know the MultiX ID of the receiving process.  The calling process need 
not know where the receiving process is located or what link type the 
receiving process uses. 
Each process, on startup, identifies itself to MultiX by calling MultiXStart.  
Among other things, when a process calls MultiXStart it:  
*	Notifies MultiX of its ID in the MultiX Network. 
*	Gives MultiX a short description of its purpose. 
*	Tells MultiX whether it wants to be a MultiX Gateway. 
Each machine can have at most one Gateway process active at any 
time.  A Gateway process is a regular process except it receives 
notification from other Gateways about new processes and about 
deleted processes.  A MultiX Gateway has full knowledge about all 
processes in a MultiX network, enabling  MultiX Gateways to provide 
rerouting services to other processes.  For example if Process "A" on an 
OS/2 machine is configured as Gateway and it is connected to Process 
"B" using an Async Line, and to process "C" using TCP/Ip, once these 
links are active, process "C" can communicate with process "B" 
through process "A" although there is no physical link between Process 
"B" and Process "C".

Communicating Between Processes 
When one process needs to communicate with another process it uses 
MdxConnectProcess.  Once the calling process initiates a connection, it 
can issue data transfer calls before the connection is actually established 
because MultiX queues all requests for data transfer until a session is 
established.  Then MultiX transmits all messages to the other process. 
No data transfer can take place between processes until a session is 
established.  Sessions are logical connections, not physical connections.

Establishing a Session 
A session is established when: 
1	The originating process calls MdxConnectProcess. 
2	The event manager (MultiX itself) notifies the receiving process of the call request.
3	The receiving process replies to MdxConnectProcess with MdxAcceptProcess.

The receiving process can refuse the session by calling MdxRejectProcess.  
When MdxRejectProcess is sent, the originator is notified, all of its queued 
messages are canceled, and no data transfer takes place until another 
connect request is issued and accepted.

Recovering from Physical Link Failure 
If the physical link fails in mid-session, the originating process' MultiX 
continues to look for the  receiving process via alternate MultiX routes 
automatically, without involving the application.

Ending a Session 
 After the originating process  calls MdxConnectProcess, MultiX 
continuously monitors the called process until the originator calls 
MdxDisconnectProcess.

Defining MultiX Process Parameters 
Every process in MultiX has process parameters which must be defined 
with the structure TMdxProcessParams, as explained in Chapter 4.

MultiX Messages 
Two processes on a MultiX Network exchange information by sending and 
receiving MultiX Messages.  A MultiX Message is an object which holds 
any type of information up to 2 Gbyte in size, unlimited by size restrictions 
imposed by the operating system (such as MS-DOS where a single buffer 
can be no longer than 64K bytes).  A MultiX message may be a file, data, or 
a material generated by the process.

Optimizing Memory Usage 
Since MultiX Messages are special objects, they have a set of APIs that 
handle the internal structure of a MultiX Message.  This enables MultiX to 
implement Messages as virtual objects on MS-DOS where memory is a very 
scarce resource.  If the programmer requests a large block of memory for 
the message, but the message requires only a small amount of memory, 
MultiX allocates the minimum amount of memory needed. 
A MultiX Message can contain information created by the process, or it can 
contain data read from a file when the message was allocated. When a file 
is sent as a message, MultiX transmits the file directly from the disk rather 
than loading the file and then transmitting the file, saving memory.  MultiX 
stores files in virtual memory, transmitting  one block at a time of a file.

Hint 
If a large message must be sent, it may be advantageous to store the 
message as a file and send the file, saving memory.

Ensuring Message Delivery 
A MultiX Message is the elementary unit of data transfer.  No matter how 
big a message or what it contains, when an application requests to send a 
message, the message is considered as "Sent Successfully" only after all 
blocks of the message arrive at the final destination.  Until all message 
blocks are received, MultiX keeps track of every block of the message.  In 
case of link or gateway failure, MultiX will recover and send each message 
from the point where it was interrupted.

Blocking and Deblocking Messages 
A MultiX Message can theoretically be any size up to 2 GB.  The 
application developer does not need to write code for blocking and 
deblocking of messages, or code for managing message queues.  MultiX 
handles all message blocking and deblocking functions as well as message 
queue management.

MultiX Message Life Cycle 
Every MultiX message has a life cycle.  A message must be created, then 
filled with data (just like someone writing a letter must first get a blank 
sheet of paper before beginning to write).  The message is then blocked and 
sent. 
On the receiving end, a message is created, the blocks which comprise the 
message appended to the new message and read.  The receiving MultiX 
acknowledges receipt to the sending MultiX, and forwards the message to 
the application. 
The message on the sending side may now be deleted, or, if the sender 
requested, the message may be deleted after the receiving application 
responds.  Finally, the receiver acts upon the message and deletes the 
message. 
The receiver has a variety of ways to acknowledge receipt of the message.  If 
the sender did not request a response (such as in a broadcast), the receiver 
need not take any action. 
The sender may require an explicit response from the receiver, (either in the 
form of MdxReply, MdxReplyWithData, or MdxReplyWithMessage).  
Once the reply is received the sender is free to delete the message. 
The sender may require confirmation from the receiving MultiX that the 
message was received.  The sender may also request to be notified if the 
message can not be delivered, as in  the case of link failure, or if the 
receiving application is inaccessible. 
The end of the message lifecycle depends on the options selected by the 
sender.  MultiX always acknowledges receipt of the message to the sender.  
For More Information Specific APIs relating to MultiX messages are dealt
with in Chapter 3, The MultiX API.

MultiX Events 
A MultiX event occurs whenever something in a MultiX network must react 
to something else.  For example, when an application receives a message, a 
MdxEvDataMsgReceived occurs.  This can be thought of as a telephone in 
a hotel.  When a guest receives a message, the light on the phone in the 
guests room begins to blink.

Event-driven Applications 
MultiX applications are event-driven.  Once an application has been 
initialized it passes control to MultiX and from then on the application is 
totally driven by MultiX initiated events.  The application does nothing 
until a MultiX event reaches its event handler (MultiX events are listed and 
explained in Chapter 4).  In turn, if MultiX has nothing to do, it passes 
control to the operating system, wasting no resources.  Once the 
application's event handler is activated, control remains with the application 
until the application returns control to MultiX.  While in the event handler, 
the application may call either operating system or MultiX routines.

The Event Handler 
The interface between MultiX applications and MultiX is the application's 
event handler.  The event handler is a user-supplied part of the application.  
The event handler is analogous to a "dispatcher".  When "confronted" with 
an event, the event handler "sends out" (calls) routines to handle the event, 
just as a dispatcher sends out workers to deal with events that have been 
brought to his attention.   
Every MultiX event invokes the event handler routine, and passes it a 
pointer to the event data or context, using the TMdxEvent structure (as 
explained in Chapter 4).

MultiX Timers 
A MultiX timer is exactly like an alarm clock.  Once the timer has been set, 
the application continues its work.  After the timer expires, MultiX informs 
the application by sending an MdxTimerEvent to the application's event handler.
An application may set as many timers as necessary.   
Note 
Times in MultiX are always indicated in   1/100  ths of seconds.

------------------------------------------------------------------------------

MultiX	MultiX	API Chapter 3


The MultiX ApplicationProgramming Interface (API)
-------------------------------------------------

MultiX is implemented as a set of user library routines which must be 
linked to the application's object code. To access the services provided by
MultiX, an application must use the MultiX API. MultiX has a simple set
of  APIs that are identical for all MultiX supported platforms.  An 
application using the MultiX API is portable and source compatible among 
platforms and operating systems. Portability is guaranteed only with respect
to services provided by MultiX.  Operating system specific calls for other 
tasks, they may not be portable.

Note
----
MultiX was developed in C, and MultiX Objects, Structures, Types, and 
Application Programming Interface (API) are in C.  This manual is directed 
primarily at C programmers.

Note
----
Times in MultiX are always indicated in 1/100 ths of seconds.

Note
----
All error messages of type TMdxApplError are found in the multix.h included on
the installation diskette.


MdxAcceptProcess 
MdxRejectProcess
----------------
Function
--------
MdxAcceptProcess is the response of a process to the event 
MdxEvCallReqReceived where the receiving process wants to 
communicate with the calling process.  If the receiving process does not 
want to communicate with the caller, it would send MdxRejectProcess.

Syntax
------
TMdxApplError	MdxAcceptProcess(TMdxProcId ProcId, 
								TMdxPassword * Password)
TMdxApplError	MdxRejectProcess(TMdxProcId ProcId, 
								TMdxCallError CallError)
Parameters
----------
ProcId			The ID number of the calling process
Password		Password expected by the caller to verify that the right process
				was called.  A null pointer means no password.
CallError		Error code explaining the reason for rejecting the call.

Return Value
------------
MdErrInvalidProcId	Invalid process ID specified.

MdErrNoMemory		MultiX was unable to allocate resources for the request.

MdxAlloc
MdxCalloc
MdxRealloc
MdxFree
---------

Function
--------
MdxAlloc allocates memory blockss.	MdxCalloc allocates
allocates memory blocks in which the bytes have been initialized to binary 0.
MdxRealloc changes the size of a previously allocated memory block.  
When a block of memory allocated by MdxAlloc, or MdxCalloc is not large 
enough, MdxRealloc first tries to allocate more memory above the 
previously allocated memory.  If there is not enough memory available 
without changing the current memory location, MdxRealloc allocates a 
new location for the memory requested.  
MdxFree frees memory allocated to MultiX.  The parameter Block is a 
pointer to memory previously allocated using MdxAlloc, MdxCalloc or 
MdxRealloc.  The number of bytes freed is the number of bytes specified 
when the memory block was first allocated (or reallocated).

Syntax
------
Void     *	MdxAlloc(UInt32 Size)
Void     *	MdxCalloc(UInt32 Size)
Void     *	MdxRealloc(Void  * Block,UInt32 Size)
Void		MdxFree(Void  * Block)

Parameters
----------
Size		The length of the memory block to be allocated.
Block		A void pointer to the previously allocated memory block, or to the
			memory block to be freed.

Return Value
------------
Pointer to allocated memory block.  If insufficient memory is available, the 
return value will be a null pointer. 
For MdxFree there is no return value.

Remarks
-------
MultiX always compiles the steps MdxAlloc, MdxCalloc, and 
MdxRealloc, regardless of whether or not the amount of memory requested 
is too big for the operating system.  If the operating system can not allocate 
this much memory, MultiX returns an error code that not enough memory is 
available.

MdxCheckLinkStatus
------------------
Function
--------
MdxCheckLinkStatus determines if a link with the designated link 
descriptor currently exists or not.  MdxCheckLinkStatus returns an error 
code if the link is inaccessible.

Syntax
------
TMdxApplError	MdxCheckLinkStatus(TLinkDescr LinkDescriptor)

Parameter
--------
LinkDescriptor		The descriptor of the link to check as returned by
					MdxOpenLink in the Ld field in TMdxLinkParams.

Return Value
------------
MdErrNoError			Link is connected and active.
MdErrInvalidLinkLd		Invalid link descriptor specified or if the
						line has been closed by MultiX because
						MaxConnectRetries or IdleTimeout as specified in
						MdxOpenLink has been reached.
MdErrLinkDisconnected	The link is currently disconnected. MultiX will
						attempt to reconnect.


MdxCheckProcessStatus
---------------------
Function
--------
MdxCheckProcessStatus determines if a process with the designated 
process ID exists or not.  MdxCheckProcessStatus returns an error code if 
the process is unavailable, if access has been denied or if the process has 
been disconnected.

Syntax
------
TMdxApplError	MdxCheckProcessStatus(TMdxProcId ProcId)

Parameter
---------
ProcId			The ID number of the process to check.

Return Value
-----------
MdErrNoError			Process is ready, and a session exists.
MdErrInvalidProcId		Invalid process ID specified or because no
						call request was ever made to or received
						from the process.
MdErrProcessNotReady	No session currently exists with the specified
						process. MultiX will continuously try to create a
						session.

MdxClrTimer
-----------
Function
--------
MdxClrTimer clears a previously defined MultiX timer, set using 
MdxSetApplTimer before the timer expires.  MdxClrTimer is used when 
the event the application is waiting for has already occurred.

Syntax
------
Void	MdxClrTimer(TTimerId TimerId)

Parameter
---------
TimerId	The MultiX assigned ID of the timer to be cleared as returned 
by MdxSetApplTimer.

Return Value
------------
No return value.

Remarks
-------
If an event has already occurred, it is advisable to clear timers related to the 
event rather than wait for the timers to expire, in order to save resources.

MdxConnectProcess 
MdxDisconnectProcess
--------------------
Function
--------

MdxConnectProcess attempts to create a session with the designated 
process.  If no session is created, MdxConnectProcess continuously 
monitors the process to connect to until the process is found, or until 
MdxDisconnectProcess is called.

MdxDisconnectProcess ends a session between two MultiX processes 
created using MdxConnectProcess, or where no session exists, stops 
attempts to create a session.

Syntax
------
TMdxApplError	MdxConnectProcess(TMdxProcessParams * ProcessParams)
TMdxApplError	MdxDisconnectProcess(TMdxProcId ProcId)

Parameters
----------
ProcessParams		Pointer to the desired process' parameters.
ProcId				The ID number of the process with which to end a session
					or with which to stop attempting to start a session.

Return Value
------------
MdErrNoError		MultiX tries to create a session with the called process.
MdErrNoMemory		MultiX was unable to allocate resources for the request.


MdxDeleteEvent
--------------
Function
--------
MdxDeleteEvent deletes the event structure passed to the event handler 
after the event occurs.  When the KeepEvent flag in TMdxEvent is set to 
true, events remain in memory until deleted by using MdxDeleteEvent.  
MdxDeleteEvent also deletes any objects pointed to by the Data field
of TMdxEvent.

Syntax
------
Void	MdxDeleteEvent(TMdxEvent * Event)

Parameter
---------
Event			Pointer to the event to be deleted.

Remarks
-------
When the event handler returns control to MultiX, MultiX deletes the event, 
its resources and pointers.  If the application wants to save the event for 
future use, it should set the KeepEvent flag in TMdxEvent to True proir to 
returning from the event handler.  When there is no further use for the 
event, the application should delete the event.


MdxGetApplTimerInfo
-------------------
Function
--------
MdxGetApplTimerInfo extracts information about expired timers from the 
Data field of TMdxEvent.  MdxGetApplTimerInfo is used only when the 
MdxTimerEvent event occurs and there is a need to get information
about a specific timer.

Syntax
------
TResult	MdxGetApplTimerInfo(Void  * Data,TMdxTimerInfo	*  TimerInfo)

Parameters
----------
Data		Void pointer to data field found in the event 
			structure for the relevant MdxTimerEvent.
TimerInfo	Pointer to where MultiX stores timer information..

Return Value
------------
Success			Request completed succesfully.
Failure			Data does not point to a valid MultiX timer structure.


MdxGetCurrTimerValue
--------------------
Function
--------
From the moment that the MultiXStart routine is run, MultiX begins 
counting 1/100 ths of seconds.	MdxGetCurrTimerValue returns the
value of this counter.	This counter is used by MultiX to run MultiX timers.

Syntax
------
TTimer	MdxGetCurrTimerValue(Void)

Return Value
------------
Current timer value.


MdxGetTime
----------
Function
--------
MdxGetTime reads the computer's clock and returns the number of seconds 
that have elapsed since 00:00:00 Greenwich Mean Time, 1 January, 1970.

Syntax
------
TMdxTime	MdxGetTime(Void)

Return Value
------------
The current time as indicated by the system clock.  For example, if the 
command MdxGetTime were given on 12:00:00 1 January, 1970 would 
return a value of 43200 sec.


MdxMsgAppend
MdxMsgRead 
------------
Function
--------
MdxMsgAppend appends information to the end of the designated message.
MdxMsgRead sequentially reads data blocks from the start of the message 
into memory.  The programmer does not have direct access to message data.  
The only way for the programmer to access message is by appending the 
data to a message, or by reading a message containing the data.

Syntax
------
TResult		MdxMsgAppend(TMdxMsg  * Msg,Void  *Data, TBufSize BufferSize)
TBufSize	MdxMsgRead(TMdxMsg	* Msg,Void	*Data, TBufSize BufferSize)

Parameters
----------
Msg			Pointer to the message to append information to or to read from.
Data		Pointer to where the data to be appended can be found, or where
			to read the data to.
BufferSize	Number of bytes to append from data to the message, or to read
			from the message.

Return Value
------------
MdxMsgRead	returns the number of bytes actually read from the message.

MdxMsgAppend returns:

Success		Data appended to the message succesfully.
Failure		MultiX was unablle to allocate resources or message has
			reached maximum size specified in MdxMsgNew.

Remarks
-------
Before a message can be appended to with MdxMsgAppend, the message 
must have been allocated with MdxMsgNew, or there must be a message 
pointer received using MdxMsgDup for a message created using 
MdxMsgNew.

MdxMsgRead is the opposite of MdxMsgAppend.  While 
MdxMsgAppend adds data blocks to the end of a message, MdxMsgRead 
sequentially reads data from the start of the message.


MdxMsgDelete
------------
Function
--------
MdxMsgDelete deletes a specified message from memory, whether the 
message was created by MdxMsgNew, MdxMsgNewFile, MdxMsgDup or 
if the message was received from elsewhere. 
When the message was created by MdxMsgDup, only the current pointer to 
the message is deleted, until the last pointer to the message is deleted.  Then 
the actual message is deleted. 
If a message was created using MdxMsgNew, MdxMsgNewFile, and not 
sent, it is advisable to delete the message using MdxMsgDelete.  If a 
message was received from another source, the massage is part of a MultiX 
event structure, and is implicitly deleted by MultiX with the event structure 
on return from the event handler.

Syntax
------
TResult	MdxMsgDelete(TMdxMsg  * Msg)

Parameter
---------
Msg		A pointer to the message to be deleted.

Return Value
------------
Success		Message succesfully deleted.
Failure		Invalid message pointer provided.

Remark 
Once a message has been deleted, neither it nor pointer to the message may 
be used again.


MdxMsgDup
---------
Function
--------
MdxMsgDup creates a new message by duplicating control information of 
an existing message.  The data of the message is not duplicated.  
MdxMsgDup creates a pointer to the same memory location as the original 
message data.

Syntax
------
TMdxMsg 	*	MdxMsgDup(TMdxMsg	* Msg)

Parameter
---------
Msg		A pointer to the message to be duplicated.

Return Value
------------
A pointer to the duplicated message data.  All future references to this 
message should refer to this pointer.  A null pointer is returned in the event 
of insufficient resources .

Remarks
-------
Use MdxMsgDup if there is a need to send the same data to multiple 
processes.  Rather than duplicate the message itself, use MdxMsgDup to 
save memory and CPU time. 
Using MdxMsgDup enables sending the same message to many different 
applications, for instance, for broadcast purposes.


MdxMsgNew
---------
Function
--------
MdxMsgNew creates a new message.  Once a new message has been 
created, use MdxMsgAppend to append information to the message.

Syntax
------
TMdxMsg 	*	MdxMsgNew(TMdxMsgSize Size)

Parameter
---------
Size		A value indicating the maximum allowable size of the message.
			This value need not be exact, since in MultiX memory is
			dynamically allocated as data is appended to the message.
			MultiX optimizes memory allocation based on the value of Size.
			In no case may the actual message length exceed the value of Size.

Return Value
------------
A pointer to the newly created message.  All future references to this 
message should refer to this pointer.  A null pointer is returned in the event 
of insufficient resources.

Warning
-------
Because MultiX monitors messages based on pointers and not content, in no 
case should the application issue a send command using the same pointer 
more than once.  If there is a need to send the same message to more than 
one application, the same message should be sent with two different 
pointers using MdxMsgDup().


MdxMsgNewFile
-------------
Function
--------
MdxMsgNewFile creates a new message where the source of the Message 
is a file.  A header string is added to the message for the use of the 
programmer.  The header allows the programmer to send information 
accompanying the file.  At the receiving side the header data is located 
before file data.

Syntax
------
TMdxMsg     *	MdxMsgNewFile(Int8Ptr Filename,UInt8Ptr Data, 
								TSCounter Length)

Parameters
----------
Filename	Name of the file to include as the message. 
Data		Message header. 
Length		Length of data string (up to 64k).

Return Value
------------
A pointer to the newly created message.  All future references to this 
message should refer to this pointer.  A null pointer is returned in the event 
of insufficient resources or if a nonexistant file is specified.

Remarks
-------
Files are transmitted by MultiX as embedded files not as linked files.  After 
transmission the source file may be altered without affecting the message.


MdxMsgSeekRead 
MdxMsgRewindRead
----------------
Function
--------
MdxMsgSeekRead sets the next location for the next read to occur.  
MdxMsgSeekRead is used if there is a need to read sections of a message 
more than once, or if there is a need to skip portions of a message. 
MdxMsgRewindRead is similar to MdxMsgSeekRead, returning  to the 
beginning message and rereading the message.  Used when there is a need 
to read the message more than once.

Syntax
------
TResult	MdxMsgSeekRead(TMdxMsg	* Msg, TMdxMsgSize OffsetSize,
						TMdxMsgSeekOrigin SeekOrigin)
TResult	MdxMsgRewindRead(TMdxMsg  * Msg)

Parameters
----------
Msg				Pointer to the message to be reread in part.
OffsetSize		Offset skip size. 
SeekOrigin		Location to skip the offset size from.  May be equal to 
				TMdxSeekStart, TMdxSeekBack, TMdxSeekFwrd, or TMdxSeekEnd.
				See Figure 3.1 for a graphic explanation.

Return Value
------------
Success or Failure.


MdxMsgSizeGet
-------------
Function
--------
MdxMsgSizeGet returns the actual size of the message, which may be less 
than or equal to the message size set in MdxMsgNew.  When a message 
was created using MdxMsgNewFile, MdxMsgSizeGet returns the size of 
the file plus the size of the header.

Syntax
------
TMdxMsgSize	MdxMsgSizeGet(TMdxMsg  * Msg)

Parameter
---------
Msg		Pointer to a message created by MdxMsgNew, 
		MdxMsgNewFile or MdxMsgDup, or received from another MultiX process.

Return Value
------------
The size of the message, or the file plus the size of the header MultiX 
added.	-1 is returned when Msg is not a valid pointer to TMdxMsg.


MdxOpenLink 
MdxCloseLink
------------
Function
--------
MdxOpenLink is used by MultiX to create a connection on the link 
specified using TMdxLinkParams.  MdxOpenLink is called only once by
an application to open a MultiX link.  Once the link is opened, the 
application does not refer to the link except to close the link, using 
MdxCloseLink, or to check for  breaks in the link using 
MdxCheckLinkStatus.

MdxCloseLink closes a MultiX link, disabling MultiX from using the link 
in future communications.  In order to use a link closed with 
MdxCloseLink, MdxOpenLink must be called to reopen the link.

Syntax
------
TMdxApplError	MdxOpenLink(TMdxLinkParams  *  LinkParams) 
TMdxApplError	MdxCloseLink(TLinkDescr LinkDescriptor)

Parameters
----------
LinkParams		Pointer to the link parameters.
LinkDescriptor	The description of the link to be closed, as returned by 
				MdxOpenLink in the Ld field in TMdxLinkParams as explained in
				Chapter 4.


Return Value
------------
MdErrNoError	Operation succesfully completed.

 
For MdxOpenLink :

MdErrLinkAlreadyOpened		Returned when the link to be opened has already
							been opened.  This is a warning,and not an error.

MdErrUnableToOpenLink		Invalid link parameters specified. Usually
							indicates that the link name specified is not valid.

MdErrLinkTypeNotSupported	The LinkType Specified is not supprted.
MdErrNoMemory				MultiX was unable to allocate resources.

 
For MdxCloseLink :
MdErrLinkClosed				Returned when the link has already been
							successfully closed.

Remarks
-------
MdxOpenLink is usually called only once per link, but can be called more 
if the link is explicitly closed by MdxCloseLink, or if the link is implicitly 
closed by MultiX if connect retries fail to reopen the link.  To find out if the 
link exists or not, use MdxCheckLinkStatus. 
If the return value of MdxOpenLink is MdErrNoError, the Ld field in
TMdxLinkParams contains a value assigned by MultiX to be used in 
future references to the link.


MdxSendMsg 
MdxReply
MdxReplyWithData
MdxReplyWithMsg
MdxSendData
----------------
Function
--------
MdxSendMsg			Sends a message from one process to another.
MdxReply			Confirms receipt of the message.
MdxReplyWithData	Sends a response to a message that contains data less than
					64 kbytes long.
MdxReplyWithMsg		Sends a response to a message containing a message more than
					64 kbytes long.
MdxSendData			Used to send a message of less than 64 kbytes from one
					process to another.

Syntax
------
TMdxApplError	MdxSendMsg(TMdxProcId ProcId, TMdxMsg  * Msg,TMdxMsgCode MsgCode,
							TMdxMsgPri MsgPri, TMdxSendAttr MsgAttr,
							TReqSeq RequestSequence,TTimer Timeout)

TMdxApplError	MdxReply(TMdxSRMsgInfo	* MsgInfo, TMdxError Error)

TMdxApplError	MdxReplyWithData(TMdxSRMsgInfo	* MsgInfo, TMdxError Error,
									Void  * Data,TBufSize DataSize,
									TMdxMsgCode MsgCode,TMdxMsgPri MsgPri,
									TMdxSendAttr MsgAttr, TReqSeq RequestSequence,
									TTimer Timeout)

TMdxApplError	MdxReplyWithMsg(TMdxSRMsgInfo  * MsgInfo, TMdxError Error,
								TMdxMsg  * Msg,TMdxMsgCode MsgCode,
								TMdxMsgPri MsgPri,TMdxSendAttr MsgAttr,
								TReqSeq RequestSequence,TTimer Timeout)

TMdxApplError	MdxSendData(TMdxProcId ProcId,Void	* Data, TBufSize DataSize,
							TMdxMsgCode MsgCode,TMdxMsgPri MsgPri,
							TMdxSendAttr MsgAttr,TReqSeq RequestSequence,
							TTimer Timeout)

Parameters
----------
ProcId			The process ID number of the receiving process.
Msg				Pointer to the message to be sent.
MsgCode			A short integer arbitrarily assigned by the user.  The message
				code is not for MultiX's use but for the receiver.  It is
				advisable that the values of message codes be known to both sides
				before communication begins.
MsgPri			A positive short integer.  Lower values indicate higher
				priorities, where 0 is the highest priority.  The lower the
				value of the message priority the sooner MultiX deals with the
				message.
MsgAttr			A flag defining the confirmation required from the receiver
				upon receipt of the message.  See remarks for possible values
				of TMdxSendAttr.
RequestSequence	User defined long integer which uniquely identifies the 
				message.  Since the same message code may be used a number of
				times the request sequence may be used by the programmer to
				distinguish the message as unique.
Timeout			Amount of time the application alots to the receiver from the
				time the message is received to the time one of the MdxReply...
				routines is called.	Failure to respond with MdxReply... generates
				an event causing the message on the sender's side to be terminated.
MsgInfo			A pointer to message found in the Data field of TMdxEvent
				where the event code is MdxEvDataMsgReceived.
Error			Comment on messages received used in responses.
Data			A void pointer to the data to be sent.
DataSize		The size of the data to be sent.


Return Value
------------
MdErrNoError				the operation completed successfully.
MdErrMsgIsEmpty 			indicated that the message contains no information.
MdErrInvalidReplyInfo		indicates that the reply information does not
							correspond to the sender of the message.
MdErrDataReplyNotAllowed	indicates that a reply containing data was
							sent where a data reply is not allowed.

Remarks
-------
Before a message or data may be sent between processes, there must at least 
be an attempt to start a session between them.  The actual message transfer 
may only begin when the "accept" has been received, which actually starts 
the session.  If an attempt was made to start the session, but there was no 
"accept", MultiX queues the message until the session exists. 
A reply is a response to a previously sent message, and never an unsolicited 
message. The only information conveyed by MdxReply is confirmation of receipt of
the message.  If a more detailed reply is needed, MdxReplyWithData or 
MdxReplyWithMsg should be used.

MdxSendData is used like MdxSendMsg, except that the message sent is 
less than 64 kbytes long, and the resulting code to be written is shorter.  For 
example, using	MdxSendMsg three steps of programming are needed to send a
short message:
...
Msg = MdxMsgNew(1000);
MdxMsgAppend(Msg,"Send Lunch",10);
MdxSendMsg(...);
...
Using MdxSendData, only one line of programming is employed:
...
MdxSendData(ToFred,"Send Lunch",10,...);
...

The parameter TMdxSendAttr is a bit mapped integer expression formed 
by combining one or more of the following manifest constants.  When more 
than one manifest constant is given, the constants are joined by the bitwise 
OR operator (|).

Constant					Meaning
--------					-------


MdxResponseRequired			MultiX waits for an explicit reply from the
							application, sent with either MdxReply or MdxReplyWithData
							or MdxReplyWithMsg.

MdxReportSuccess			MultiX on the sender's side waits until MultiX on
							the receiver's side confirms that the message
							has been received.

MdxReportError				MultiX notifies the sender if the message can not
							be sent. Either the receiving process is inaccessible
							or the link has broken.

MdxResendOnRestart			If the receiver disappears during transmission MultiX
							resends the message when the receiver restarts.


MdxSetApplTimer
---------------
Function
--------
MdxSetApplTimer is used by the application to set a MultiX timer.

Syntax
------
MdxTimerId	MdxSetApplTimer(Int16 Code,TTimer Time, TTimerTag Tag1,
							TTimerTag Tag2,TTimerTag Tag3, TCounter Counter)

Parameters
----------

Code			User defined timer code.  Used to classify the timer.  Timer
				codes can be used to identify timers after timers expire.
				The use of timer codes is implementation dependent.
Time			Amount of time in 1/100 ths of seconds to allocate before the
				timer expires.
Tag1-3			Three user defined 32 bit integer variables that may be used
				to provide additional information about the timer. For example,
				one tag may be a process ID, another an error code, and the
				third a link ID.  These tags may help the programmer distinguish
				between timers that have the same timer code.
Counter			Number of times to use the timer.  If set to 1, the timer
				repeats indefinitely.

Return Value
------------
An ID for the timer, used to identify the timer for future reference.  In 
particular, used in MdxClrTimer.

MdxTimeTo_time_t
----------------
Function
--------
Where the operating system does not use 1 January, 1970 as the standard 
for its clock, MdxTimeTo_time_t converts TMdxTime to a time the 
operating system recognizes.

Syntax
------
time_t	MdxTimeTo_time_t(TMdxTime Time)

Parameter
---------
Time		The time returned by MdxGetTime.

Return Value
------------
The converted time.


MultiXStart
-----------
Function
--------
Every MultiX application must call the MultiXStart routine once to 
initialize MultiX before beginning any other work with MultiX.

Syntax
------
Void	MultiXStart(TMdxProcId ProcId,Int8Ptr String,
					TMdxStartupAttributes StartupAttributes)

Parameters
----------
ProcId				The MultiX Process ID of the starting up process,
String				User defined, free text, up to 23 byte long null terminated string.
StartupAttributes	A bit mapped integer expression formed by combining 
					one or more manifest constants.

Remarks
-------
The parameter StartupAttributes is a bit mapped integer expression formed 
by combining one or more of the following manifest constants.  When more 
than one manifest constant is given, the constants are joined by the bitwise 
OR operator (|).

Constant						Meaning

MdxStartAsGateway				Specifies that the process is defined as
								a MultiX gateway.  Only one MultiX gateway is
								allowed per computer.
MdxReportAllProcesses			Whenever MultiX detects a transition such as
								the addition of a new process, or a change in
								readiness of a process, MultiX generates an
								event. If this is not specified in startup,
								MultiX does not notify the user of transitions.
								MdxReportAllProcesses is primarily for use by
								gateway processes.
MdxReportAllLinks				Whenever MultiX detects a transition such as
								the addition of a new link, or a change in
								readiness of a link, MultiX generates an event.
								If this is not specified in startup, MultiX
								does not notify the user of transitions.
								MdxReportAllLinks is primarily for use by
								gateway processes.


MultiXWaitEvent 
MultiXCheckEvent
----------------
Function
--------
MdxWaitEvent gives MultiX total control of the application until a MultiX 
event activates the application through the application event handler.  The 
application performs no activity until an event is passed to the event 
handler. 
Unlike MdxWaitEvent, if MdxCheckEvent is called, MultiX returns 
immediately to the caller if there are no events, giving the application some 
freedom from MultiX.

Syntax
------
Void	MultiXCheckEvent(Void) 
Void	MultiXWaitEvent(Void)

Remarks
-------
CheckEvent and WaitEvent may not be called from within the MultiX event 
handler. 

------------------------------------------------------------------------------

MultiX	MultiX Structures and Types	Chapter 4

MultiX Structures and Types
---------------------------

This chapter describes MultiX structures and types used to develop a 
MultiX based application.  All structures and definitions are found in the 
file multix.h located in the distribution diskette.  This file must be included
in the compile unit for compilation to succeed.

TMdxLinkParams Structure
------------------------

typedef struct TMdxLinkParams 
{
	TLinkDescr		Ld;
	TMdxLinkType	LinkType;
	TMdxLinkName	LinkName;
	TBaudRate		LinkBaud;
	TBoolean		UseDlcFraming;
	TMdxNetAddr		NetAddr;
	TSIndex			L2DriverIndex;
	TSIndex			L3DriverIndex;
	TMdxLinkStatus	For internal use;
	TMdxService		Service;
	TMdxConnectMode	ConnectMode;
	TTimer			ConnectTimeout;
	TTimer			ConnectRetriesDelay;
	TBufSize		L1MaxSendSize;
	TCounter		MaxConnectRetries;
	TTimer			IdleTimeout;
	TTimer			ImAliveInterval;
	TTimer			PollInterval;
	TSCounter		MaxPollRetries;
	TMdxProcId		DefaultProcId;
}	TMdxLinkParams;


Fields:
Ld (Link Descriptor)	Value returned by MdxOpenLink.	To
						be used when calling MdxCheckLinkStatus and
						MdxCloseLink.

LinkType				Type of link.  See below for possible values.

LinkName				Value depends on link type.  See below for possible
						values.

BaudRate				Baud rate for asynchronous lines.  300 to 38k baud.

UseDLCFraming.			Use DLC framing.	True for Async and TCP/Ip.

NetAddress				Address in X25 network.  No default.

L2DriverIndex			Always 0.

L3DriverIndex			Always 0.

Service					MdxLinkTypeAsyncModem - gives modem dialing commands,
						such as "ATDP2126581234".
						MdxLinkTypeTcpIpSocket - socket name as is found in
						the "services" file.

ConnectMode				Listen or call.
						MdxConnectModeListen -	Wait for incoming call.
						MdxConnectModeCall - Initiate contact over the link.

ConnectTimeout			Connect time-out.  Amount of time to wait
						for a connection to bestablished.
						Default - indefinite.

ConnectRetriesDelay		Connect retries delay.	Amount of time to wait
						between retries.

MaximumConnectRetries	Maximum connect retries to attempt.

L1MaxSendSize			On reliable lines such as TCP/Ip use large
						values.  On noisy lines use smaller values.
						Maximum recommended value is 4k.

IdleTimeout				A positive number indicating the amount
						of time MultiX waits on an idle line until
						ending the connection.	When this timer
						expires on an idle link, the link is closed
						and not reopened by MultiX.  To use the
						link again, the application must open the
						link again.
						For a modem, set this at a low value to
						avoid high telephone charges.
						0 = do not hang up.

ImAliveInterval			At this interval MultiX on the sending
						side contacts MultiX on the receiving side
						to determine that the other side is still
						alive.	If an answer is received to this
						query, MultiX takes no action.	If no
						answer is received, MultiX notifies the
						process using this link.
						0 = disabled.

PollInterval			At this interval of seconds MultiX asks the
						receiver to verify what has been received.
						Default 300.

MaximumPollRetries		If after this amount of retries no
						verification of receipt is received MultiX
						assumes the receiving side is dead.
						Default 5.

DefaultProcessId		Always 0.


ConnectTimeOut, ConnectRetriesDelay, and MaximumConnectRetries

The fields connect time out, connect retries delay and maximum connect retries, respectively,
are related. MultiX waits the connect Timeout, to establish a connection over
the link.  After each connect retry delay, MultiX attempts a new call.  If 
after the maximum connect retries no connection is established, MultiX 
stops trying to establish contact.  To attempt contact again, the application 
has to reopen the link.

ImAliveInterval, PollInterval and MaxPollRetries

ImAliveInterval, PollInterval and MaxPollRetries, respectively, are related.  
MultiX uses these parameters to isolate link failures.  Every 
ImAliveInterval, MultiX asks the receiving side to verify that it is still 
receiving.  Every PollInterval MultiX checks internally for unconfirmed 
frames, and if it finds any asks the receiver to confirm what has been 
received.  If no confirmation is received after the MaxPollRetries number of 
retries, MultiX assumes the link to the receiver is no longer working.  If a 
large poll interval is selected, MultiX takes longer to find link failure.  If a 
small poll interval is selected, polling interferes with communication.  
MultiX provides defaults which attempt to balance between these 
considerations.

TMdxLinkType Values

Possible Values of TMdxLinkType			Possible Values of TMdxLinkName

MdxLinkTypeAsyncLocal					Async port name.  For example, in
MdxLinkTypeAsyncModem					DOS, Windows or OS/2, "COM2".  In
										UNIX "/dev/tty1".

MdxLinkTypeNetBios						A Name in the NetBIOS network, such
										as Server 1, Client 1.

MdxLinkTypeTcpIpSocket					Name of the host on the TCP/Ip
										network.  This name must be in the
										"hosts" file on the callers machine.


MdxLinkTypeSpxIpx						Any valid service name in Netware network.


TMdxProcessParams Structure
---------------------------

typedef	struct	TMdxProcessParams
{
	TMdxProcId		ProcId;
	TMdxPassword	PasswordToSend;
	TMdxPassword	ExpectedPassword;
	TTimer			InactivityTimer;
	TTimer			ConnectRetriesInterval;
}	TMdxProcessParams;


Fields:

ProcessID						Any long integer assigned by the
								programmer or system manager to
								identify the process.

PasswordToSend					(optional)	See explanation below.

ExpectedPassword				(optional)	See explanation below.

InactivityTimer					When MultiX receives notification
								that the receiving side has
								disappeared MultiX waits the
								duration of the inactivity timer.  If
								the receiving process is recovered
								within this time MultiX begins
								transmitting the message blocks
								from where it was cut off.	If the
								process is not recovered the session
								is ended.  Default: 30 seconds.

ConnectRetriesInterval			How frequently to check for the
								called process in the network.	The
								search is interrupted when the called
								process is found.
								Default: 10 seconds.

Passwords

Passwords are used when the programmer desires a safeguard that the 
processes communicating are the correct ones.  MultiX automatically sends 
the passwords when the application calls MdxConncectProcess If the 
originator's password is acceptable to the receiver, the receiver replies with 
MdxAcceptProcess. 
In MultiX it is possible that two processes will both originate a 
communication.  In this instance, both PasswordsToSend must identically 
match both ExpectedPasswords.  If the passwords do not match, MultiX 
will reject the communication without notifying the processes.  If the 
passwords are correct, MultiX notifies the application, which sends back the 
MdxConnectProcess call.  Refer to Figure 4.1 
  
Figure 4.1	Matching Passwords

TMdxSRMsgInfo Structure
-----------------------

TMdxSRMsgInfo is a structure pointed to by the Data field of the event 
structure of the message related event, MdxEvDataReplyReceived or, 
MdxEvSendMsgCompleted.  This structure holds the information relating 
to the message itself. 
If a process sends more than one message, MultiX ensures that when 
responses are received, that the right reply reaches the right message.  
TMdxSRMsgInfo is used by MultiX to verify that a received response 
matches the correct message.


typedef	struct	TMdxSRMsgInfo
{
	struct
	{
		TMdxMsg			*Msg;
		TMdxMsgCode		MsgCode;
		TMdxProcId		SentFrom;
		TQueueSeq		SenderMsgId;
		TMdxSendAttr	SendAttr;
		TMdxMsgPri		MsgPri;
	}	Received;
	struct
	{
		TMdxMsg			*Msg;
		TMdxMsgCode		MsgCode;
	}	Sent;
}	TMdxSRMsgInfo;



Fields

Msg (Received)					Pointer to the message received.

MsgCode (Received)				Message code of the response sent.

SentFrom						Process ID of the sending process as
								defined in Process Parameters (see Page 4.6).

SendAttr						Defines the confirmation required from
								the receiver upon receipt of the
								message.  See Chapter 3 for possible
								values of TMdxMsgAttr.

MsgPri							A positive short integer indicating the
								message priority as assigned by the sender.

Msg (sent)						Pointer to the original message sent.

MsgCode (sent)					Message code of the original message sent.


TMdxEvent Structure
-------------------

typedef	struct	TMdxEvent
BEGIN
	TMdxEventCode	Code;
	TLinkDescr		Ld;
	TMdxError		Error;
	TReqSeq			ReqSeq;
	TMdxProcId		ProcId;
	Void			*Data;
	TBufSize		DataCount;
	TMdxEventHandlerIndex	DataDestructorIndex;
	TBoolean		KeepEvent;
	TMdxObjectId	Id;
	TTimer			EventTimer;
END	TMdxEvent;


Fields


Code					The code for the event as specified beginning on
						page 4.10.

Ld						Value returned by MdxOpenLink.	To be used when calling
						MdxCheckLinkStatus and MdxCloseLink.

Error					Event dependent.  For example, if upon SendComplete
						Error is greater than 0, the message was not
						successfully sent.	The value of TMdxError explains why.

ReqSeq					Optional.  User defined long integer of the type
						TReqSeq uniquely identifying the message.  Since the
						same message code may be used a number of times, the
						request sequence is used to distinguish the message
						as unique.

ProcId					The process ID of a process with which a session
						exists.

Data					A void pointer to an event dependent data structure.

DataSize				Used by MultiX.

KeepEvent				When the Application's Event Handler is finished,
						MultiX destroys data which is part of the event.
						If the data should be preserved, set the KeepEvent
						flag to True. If KeepEvent is set to True, the
						application must later delete the event using
						MdxDeleteEvent.
						True	=	Keep.
						False	=	allows MultiX to delete the event.


TMdxEventCode Value Codes
-------------------------

MdxEvDataMsgReceived			Indicates the arrival of a new message
								received by MultiX to be processed by the
								application. The only field of interest in
								TMdxEvent to the application is "Data".	Data
								points to a structure of the type TMdxSRMsgInfo.
								Using that pointer, the application can retrieve
								information from the message received.

MdxEvDataReplyReceived			Indicates receipt of a reply from a process
								with which communication is already in progress.
								TMdxSRMsgInfo contains all the information about
								the message that was sent and the reply that was
								received, enabling the application to associate
								the reply with the original message. This event
								also indicates that the other end processed the
								message that was sent and no error occurred so
								the sender can assume successful processing of
								the original message.

MdxEvSendMsgCompleted			Indicates that a process to which a message was
								sent earlier has been terminated. The error field
								in TMdxEvent indicates whether the message was
								successfully sent or not. Any value other than
								MdErrNoError indicates that the request failed
								either because MultiX could not forward the message
								to its destination or because the other process
								rejected the message with an error reply. The
								Error explains why the send failed.	"Data" points
								to a structure of the type TMdxSRMsgInfo. Using
								that pointer, the application can retrieve information
								from the message received.

MdxEvCallReqReceived			Indicates that another process is trying to establish
								a session with the receiving process.  "ProcId"
								in TMdxEvent holds the MultiX Id of the calling
								process, "Data" points to TMdxPassword.

MdxEvCallRejected				Indicates that the called process has refused
								a call, and there is no way to establish a session
								with that process.	The error field contains the
								reason for rejection, as set by the called process
								responding with MdxRejectProcess.

MdxEvCallCompleted				Indicates that a session was established between
								the calling process and the process indicated
								by "ProcId" in TMdxEvent. This means that data
								transfer can take place.

MdxEvProcessReady				When a process with which a session exists changes
								states from not ready to ready, a MdxEvProcessReady
								event is generated.	The ProcID field in TMdxEvent
								indicates the subject of the event.

MdxEvProcessNotReady			When a process with which a session exists changes
								states from ready to not ready, a MdxEvProcessNotReady
								event is generated.	The ProcID field in TMdxEvent
								indicates the subject of the event.

MdxEventApplInit				An application may not call any MultiX routines
								before it calls MultiXStart. Once MultiX finishes
								its initialization it invokes the application's
								event handler with event code of MdxEventApplInit.
								That indicates to the application that it can
								call any MultiX routine.

MdxTimerEvent					Each time an application timer expires, MultiX
								invokes the application's event handler with
								MdxTimerEvent. Access information about the timer
								using the data field in TMdxEvent.

MdxLinkMgrEvLinkStatus			When a link previously opened with MdxOpenLink
								changes state, a MdxLinkMgrEvLinkStatus event
								is generated. An event of this type is generated
								when the IdleTimeout or MaxConnectRetries fields
								in TMdxLinkParams are reached. The Data	field
								in TMdxEvent points to a structure of the type
								TMdxLinkParams passed by the application to
								MdxOpenLink. This event occurs only if MdxReportAllLinks
								is set in MultiXStart.
								The Error field in TMdxEvent indicates the current
								state of the link.
								MdErrNoError			-	the link is ready.
								MdErrLinkDisconnected	-	the link is broken.
															MultiX will try to
															reestablish contact.
								MdErrLinkClosed 		-	the link is broken.
															MultiX will not try to
															reestablish contact.

MdxProcMgrEvProcessAdded		When a process in the network changes states from
								not ready to ready, a MdxProcMgrEvProcessAdded
								event is generated.	The ProcID field in TMdxEvent
								indicates the subject of the event.

MdxProcMgrEvProcessRemoved		When a process in the network changes states from
								ready to not ready, a MdxProcMgrEvProcessRemoved
								event is generated. The ProcID field in TMdxEvent
								indicates the subject of the event.


TMdxApplTimerInfo Structure
---------------------------

typedef	struct	TMdxApplTimerInfo
{
	TTimerId		TimerId;
	Int16			Code;
	TTimer			Timer;
	TTimerTag		Tag1;
	TTimerTag		Tag2;
	TTimerTag		Tag3;
	TCounter		Count;
}	TMdxApplTimerInfo;

Fields

TimerId 			Returned by MultiX when calling MdxSetApplTimer(). Each
					timer has its own Id which can be used later to clear the
					timer using MdxClrTimer().

TimerCode			Timer code. Used to classify the timer, just as a MultiX
					message code classifies a message.	See Chapter 3 for more
					information about MultiX message codes.

Timer				Amount of time to allocate before the timer expires.

Tag					One of three 32 bit user defined variables.	These may be
					used to provide additional information about the timer.
					For example, one tag may be a process ID, another a message
					code, and the third a link code.

Counter				The number of times to apply the timer.	For example, if
					Timer is 1000, and Counter is 10, MultiX applies a
					ten second timer ten times.
