Important: The information in this document is obsolete and should not be used for new development.
Using Ports
This section describes how to obtain port information, and how to register as an Open Transport client.Obtaining Port Information
If your application manipulates ports, you may need port information to locate a specific port or to find out how what ports are registered on your computer. Open Transport registers all ports on your computer and creates a port structure for each port. You can then use the various Open Transport port functions to access these structures and get information from them. The port structure is described in "The Port Structure".If you want to find out the port associated with a given provider, you can use the
OTGetProviderPortRef
function. If you don't know which port structure you want or if you want to provide a list of user-readable port names to your user, you can use theOTGetIndexedPort
function to iterate through all the ports available on a computer, obtaining the port structure of each.There are also two functions you can use to find the port structure for a specific port: If you know its port name, you can use the
OTFindPort
function, or if you know its port reference, you can use theOTFindPortByRef
function.If you want to use the
OTFindPortByRef
function, you need a port reference. There are several ways you can get one: Another application might have passed it to you, another application could have put it into a port structure that you can access by using theOTGetIndexedPort
function, or you can create one.To create a port reference, you use the
OTCreatePortRef
function. You must know all the port's hardware characteristics: its device and bus type, its slot number, and its multiport identifier (if it has one). You cannot use wildcards to fill in any element you don't know. Possible device and bus types are described in "The Port Reference".For example, if you want to find out the port name of the Ethernet port in NuBus slot 13, you can use this line of code to create a port reference for this port:
OTPortRef ref = OTCreatePortRef(kOTNuBus, kOTEthernetDevice, 13, 0);If you then pass the result of this call to theOTFindPortByRef
function,OTFindPortByRef
fills a buffer with the port structure that has this port reference and returns a pointer to the buffer. You can examine the port structure's fields for its port name.Open Transport has predefined variants of the
OTCreatePortRef
function for the most commonly used hardware devices such as the NuBus, PCI, and PCMCIA devices. These are found in the section describing the functionOTCreatePortRef
.If you want to extract information from a port reference, you have to use specific Open Transport functions:
OTGetDeviceTypeFromPortRef
,OTGetBusTypeFromPortRef
,OTGetPortIConFromPortRef
,OTGetUserPortNameFromPortRef
, andOTGetSlotFromPortRef
.
Listing 8-1 Finding all serial ports
- Note
- Listing 8-1 shows the user-defined function
OTFindSerialPorts
. This function uses theOTGetIndexedPort
function to find all valid ports. For each port, it gets and examines the device type and, if it's a serial port and not an alias, it calls the user-definedPrintSerialPort
function to output information about the port. (Note that you don't want to include aliases to the serial ports in the list, otherwise a standard machine will have 3 serial ports, "serialA", "serialB"and "serial". ThePrintSerialPort
function uses theOTGetUserPortNameFromPortRef
function to print the user name for each port.Note that the slot numbers for NuBus(TM) cards are physical; that is, they are the slot numbers returned by the Slot Manager and not the slots seen in various network configuration applications. Physical slot numbers depend on the type of card installed. For example, NuBus cards number their slots 9 to 13, which appear in the AppleTalk or TCP control panels as slots 1 to 5. For PCI cards, however, the slot numbers are their logical slot IDs as defined in the port structure. For cards in a PCI bus, it is not possible, a priori, to create a port reference that corresponds to a known card, so applications must iterate through the port registry to find appropriate PCI ports.
static OSStatus OTFindSerialPorts(void) { OSStatus err; Boolean portValid; SInt32 portIndex; OTPortRecord portRecord; UInt16 deviceType; /* Start portIndex at 0 and call OTGetIndexedPort until */ /* there are no more ports. */ portIndex = 0; err = kOTNoError; do { portValid = OTGetIndexedPort(&portRecord, portIndex); /* Get the deviceType; and, if it's a serial port */ /* and not an alias, call PrintSerialPort */ if (portValid) { deviceType = OTGetDeviceTypeFromPortRef(portRecord.fRef); if (deviceType == kOTSerialDevice && (portRecord.fInfoFlags & kOTPortIsAlias) == 0) { err = PrintSerialPortInfo(&portRecord); } } portIndex += 1; } while ( portValid && err == kOTNoError); return err; } static OSStatus PrintSerialPortInfo(const OTPortRecord *portRecord) { Str255 userVisibleName; /* You must be running PPC codeto call OTGetUserPortNameFromPortRef */ /* on a PPC machine. */ OTGetUserPortNameFromPortRef(portRecord->fRef, userVisibleName); printf("Found a serial port with port reference $%08lx:\n", portRecord->fRef); printf(" User visible name is "%#s".\n", userVisibleName); printf(" String to pass to OTCreateConfiguration is "%s".\n", portRecord->fPortName); printf(" Name of provider module is "%s".\n", portRecord->fModuleName); printf("\n"); return kOTNoError; }Requesting a Port to Yield Ownership
There may be times when you need to use a particular port (normally, a serial port or modem) that is owned by another application. You can use theOTYieldPortRequest
function to request the owner of a port to yield the use of the port to you. (Check thekOTPortCanYield
bit in the port record's flags field to determine whether the port supports yielding.) Open Transport then issues akOTYieldPortRequest
event to each provider of any registered clients for that port for acceptance or refusal. If the owner has not registered as a client of Open Transport, compliance is assured.If the current owner wants to deny the request, it puts a negative error code into the
fDenyReason
field in the port close structure indicating its reason for refusal. TheOTYieldPortRequest
function then returns with this error code as its result and with a buffer listing all the clients that have refused the request, (normally only one).If the
OTYieldPortRequest
function returns without an error, the port is available for your use. You can then bind it with a queue length (qlen
) greater than 0 or establish a connection with it. If you don't use the port within a short period of time (typically 10 seconds), the port automatically stops being available for your use and reverts to its original owner.You can force a passive client to yield by using a value of
NULL
in theOTYieldPortRequest
function'sbuffer
parameter. When the function returns without an error, the port is available. Note that a port can only be yielded in this manner if its current client is passively listening; it cannot be yielded if a connection is in progress.Providers owned by unregistered clients need to be prepared to receive
kOTProviderIsDisconnected
andkOTProviderIsReconnected
events when the connection between the provider and port is unexpectedly disconnected and reconnected due to a successful yield request.Registering as an Open Transport Client
You can use theOTRegisterAsClient
function to register your application as an Open Transport client and provide Open Transport with a notifier function for sending messages to you. Once you are registered as a client, Open Transport can notify you of system events, such as the port transition events that occur when a particular port is disabled or closed and when it is reenabled. By registering, you also provide Open Transport with a user-readable name to use when informing the user of port transition events.If you use the
OTRegisterAsClient
function to register a notifier for client events, you would receive the events such askOTPortDisabled
,kOTPortEnabled
,kOTPortOffline
,kOTPortOnline
,kOTClosePortRequest
,kOTYieldPortRequest
, andkOTNewPortRegistered
to keep you informed. For information about port events, see "Port-Related Events".
The OTRegisterAsClient
function is optional. If you do not want to receive these events, you do not have to call this function.Calling the
CloseOpenTransport
function automatically unregisters you as a client. If you want to unregister prior to callingCloseOpenTransport
, you can call theOTUnregisterAsClient
function.
- Note
- Client notifiers are distinct from a provider notifier. Provider notifiers tell you about events related to that specific provider. Client notifiers are sent events about the Open Transport system as a whole.
Subtopics
- Obtaining Port Information
- Requesting a Port to Yield Ownership
- Registering as an Open Transport Client