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.