Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Networking With Open Transport / Part 1 - Open Transport Essentials
Chapter 3 - Providers


About Providers

A provider is a layered set of protocols, implemented by STREAMS modules, that provides some kind of data-oriented service. That service might be implementing a networking protocol, encrypting data, filtering data, and so on. When you configure a provider, you can layer the modules that implement the provider to create an arbitrarily complex service. For example, you can place an encryption module above the AppleTalk Data Stream Protocol (ADSP) module. This combination would provide a stream of network data that was secure from snooping on the network.

Open Transport defines three main types of providers:

An endpoint provider offers a service that creates connections and moves data from one logical address to another. A mapper provider offers services that you use to associate, or "map," network entity names with network addresses. A service provider lets you perform tasks that are specific to a particular protocol, such as AppleTalk or TCP/IP. Each protocol family has the option of providing a service provider if one is needed.

In the normal course of events you do not communicate directly with the STREAMS modules that make up a provider. For example, to use an endpoint provider, you must open an endpoint and use the functions defined in the Open Transport application programming interface (API) for endpoints. The Open Transport API shields your application from the details of the provider implementation, allowing your application to run with little or no change, even when the implementation of the provider is changed, or updated.

To use a provider, you must initialize Open Transport and then call the function that opens the provider. When that function returns, it passes back to you a reference to the provider you have just created. A provider reference is like a file handle or a driver reference number. It associates a function called from your application with a specific provider that must implement the function; you pass the provider reference as a parameter to all provider functions. The data type of a provider reference depends on the type of the provider (endpoint reference, mapper reference, AppleTalk service reference, and so on).

You can open one provider or many. For example, a server application might open many providers and use them concurrently. The number of providers you can create is limited mainly by the availability of memory. The memory used to create a provider comes partly from your application heap but mostly from the system heap.

C++ note

The C++ API for Open Transport includes a class called TProvider that is the superclass for all provider-related member functions. Endpoint functions are in class TEndpoint, mapper functions are in class TMapper, and service provider functions are in classes corresponding to specific protocol stacks. For example, the classes TAppleTalkServices and TInternetServices contain AppleTalk-specific and TCP/IP-specific member functions.

In object-oriented programming parlance, endpoints, mappers, and the data structures maintained by Open Transport for service providers are all objects. An endpoint, for example, is an object instantiating the class TEndpoint. An endpoint contains all the data that Open Transport needs to link together software modules, drivers, and hardware for a specific endpoint provider. All of the Open Transport API functions except the functions that open providers and some utility functions are included in the class definitions of the various classes of providers.

You can call public member functions of the TProvider class for provider objects of any type: these functions are the general provider functions. Public member functions defined in a subclass of the TProvider class (for example, TEndpoint) can be called only for providers belonging to that subclass--in this example, only from the TEndpoint subclass. These functions are the type-specific provider functions. Note that, as with endpoints and mappers, each kind of service (for AppleTalk, TCP/IP, and so on) derives directly from the TProvider class; there is no other class for services-type providers.

Provider Functions

Functions that manipulate providers are known as provider functions. Some provider functions can manipulate providers of any type. These are called general provider functions and they are documented in detail in "Providers Reference". You use general provider functions to

In addition to the general provider functions, each type of provider has type-specific provider functions; these functions work with only that particular type of provider. For example, endpoint functions work only with endpoint providers, and mapper functions work only with mapper providers. Each type of service provider (for AppleTalk, TCP/IP, and so on) has its own type-specific provider functions.

Provider functions that accept a provider reference of type ProviderRef are general: they accept any other type of provider reference as well. But functions that require a type of provider reference other than ProviderRef (for example, EndpointRef) are type-specific: they accept only that type of provider reference.

Interrupt-Time Processing

The Open Transport functions that you can call and the means by which you call them vary with the level of execution: system task time, deferred task time, and hardware interrupt time.

In general you can call all Open Transport functions at system task time and most Open Transport functions, asynchronously, at deferred task time. At hardware interrupt time, you are much more limited: you cannot call any of the provider functions and you can call only a small number of Open Transport functions. Software executed at hardware interrupt level includes installable interrupt handlers for NuBus and other devices, Time Manager tasks, VBL tasks, and routines called from within a hardware interrupt handler.

Because it is possible to call many more Open Transport functions from deferred-task level than from hardware-interrupt level, if you need to call an Open Transport function from hardware-interrupt level, you can use the Open Transport function OTScheduleDeferredTask or the system function DTInstall to have those functions execute at deferred task time. Deferred tasks are scheduled to run when all other hardware interrupt processing is done but before system task processing resumes.

For more information about execution levels and deferred tasks, see Inside Macintosh: Processes. For a more detailed view of processing and Open Transport, see Chapter 5, "Programming With Open Transport." For a list of those functions you can call at hardware-interrupt level and deferred-task level, see "Special Functions".

Modes of Operation

For each provider, you can use general provider functions to specify how providers execute, whether the provider can block when sending or receving data, and whether endpoint providers acknowledge sends.

A provider can execute in synchronous mode or in asynchronous mode. In synchronous mode, provider functions return only when they complete execution. In asynchronous mode, they return as soon as they are queued for execution.

A provider's blocking status affects how functions that send and receive data behave when they must wait to complete an operation. If a provider is blocking, it either waits for as long as it takes to send or receive data (for a synchronous call) or it returns with a result indicating why the operation could not be done immediately (asynchronous call). If a provider is nonblocking, the provider attempts to send or receive data and, if it cannot do so immediately, it returns with a result indicating why it could not complete the operation.

A provider's mode of execution and blocking status act together to control the provider's behavior. There are four possible combinations; of these, though only three offer a practical use:

A provider's blocking status also governs what happens when you close a provider. In non-blocking mode, closing the provider flushes all outgoing commands in the stream and immediately closes the provider. In blocking mode, the stream is given up to 15 seconds per module to allow outgoing commands to be processed before the stream is closed.

A provider's send-acknowledgment status determines whether endpoint functions that send data make an internal copy of the data before sending it. Open Transport ignores the send-acknowledgment status for mapper and service providers.

For specific recommendations about which mode to use and how to set that mode, see "Controlling a Provider's Modes of Operation".

Provider Events

Open Transport defines three kinds of events called provider events. These events are unique to the Open Transport architecture and are not events in the usual Macintosh sense: they are not processed by the Event Manager, and they have no associated Event Record. Rather, Open Transport uses provider events to inform your application that something has occurred which demands your immediate attention or to signal the fact that a function executing in asynchronous mode has completed. The first kind of provider event is called an asynchronous event, the second kind is called a completion event, and the third kind is called a miscellaneous event. In this book, the term event refers to a provider event, except where noted otherwise.

A provider uses asynchronous events to notify your application that data has arrived or that a request for a connection or disconnection is pending. Most asynchronous events defined for Open Transport have equivalents in the X/Open Transport Interface (XTI), from which the Open Transport interface derives.

XTI does not define completion events. A provider uses completion events to notify your application that an asynchronous function has finished executing. Some functions are inherently synchronous and have no corresponding completion event. For example, if an endpoint provider is in asynchronous mode and you execute the OTGetEndpointState function, the function returns information about the state of the endpoint immediately. The description of a function indicates whether the function behaves differently in asynchronous mode.

Miscellaneous events are used to notify you or warn you of a change of state in the provider: for example, the provider is about to be closed.

A provider event is identified by a provider event code. These are listed and described in the event codes enumeration .

In general, to receive notice of provider events, you must provide a notifier function and install it for the provider. A notifier function is a function that you write and that the provider will call when an event occurs. When the provider calls this function, it uses the function's parameters to pass back information about the event that occurred, and if this is a completion event, it also passes back additional information about the result of the function that completed and a pointer to any other information passed back by the function. The section "Using Notifier Functions to Handle Provider Events" provides additional information about notifier functions and the issues involved in asynchronous processing. You can also refer to "Using Notifier Functions" for a description of the notifier functions.

Function Results

Most Open Transport functions return a result of type OSStatus or OTResult. The main difference between these is that a result of type OSStatus is either 0 (kOTNoError) or a negative number indicating an error code; a result of type OTResult can be either a positive value whose meaning varies with the function called or a negative value indicating an error code. Appendix B lists all result codes returned by Open Transport.

The discussion of functions in the reference section of this book describes the meaning of the errors that are most likely to occur for each function. In addition, every Open Transport function might return the result codes listed in Table 3-1. For additional information, please look up the meaning of these result codes in Appendix B .

Table 3-1 Result codes that all Open Transport functions can return
Result codeMeaning
kEBADFErrThe provider reference you supplied is invalid.
kOTBadSyncErrYou made a synchronous call at an inappropriate level.
kENOMEMErrThere is not enough memory to complete the request.
kENOSRErrThere are not enough system resources to complete the request.
kEAGAINErr

kEWOULDBLOCKErr

A provider is in non-blocking mode and Open Transport would have to block to complete the request.
kOTProtocolErrAn unspecified protocol error occurred. This is usually fatal. To recover, close the provider.
kOTClientNotInittedErr  You have not initialized Open Transport or Open Transport Utilities.
kOTOutStateErrThe endpoint is not in an appropriate state for the operation you wish to execute.
kOTStateChangeErrThe endpoint is undergoing a transient state change. This error is returned when you call a function while an endpoint is in the process of changing states. You should wait for an event indicating the endpoint has finished changing state and call the function again. The provider also returns this error if you attempt to call an "incompatible" function while another operation is still ongoing; for example if you call the function OTSndUData while a call to the OTOptionManagement function is still outstanding.


Subtopics
Provider Functions
Interrupt-Time Processing
Modes of Operation
Provider Events
Function Results

Previous Book Contents Book Index Next

© Apple Computer, Inc.
15 JAN 1998