Using the Link Layer API


Open Physical Port

The API requires a device handle obtained from the MgslOpen call. The application must configure and control the port as necessary to carry link layer traffic. This typically involves configuring the desired parameters, asserting DTR, waiting for DCD to go active, and enabling the receiver. Refer to the base API documentation for details about configuring and controlling the physical port.

Allocate Link Instance

The link layer API requires at least one link instance. Call MgslDlAllocate to allocate a link and obtain a link identifier for use with other API calls. The default link state after allocation is disconnected mode. (DLSTATE_RELEASED)

The number of required links is application dependent. The API supports multiple links operating simultaneously over a single physical port. Each link maintains separate configuration and state information. Call MgslDlAllocate for each required link.

Data exchanged over a single physical port is multiplexed to multiple links using the address field of the HDLC frame. Each HDLC address requires an allocated link to accept and create data for that address.

Configure Common Link Parameters

Some link layer parameters are common to all link instances on a physical port. Configure these parameters with the MgslDlSetPhysParams and MgslDlGetPhysParams functions. These functions use the MGSL_DLPHYSPARAMS structure.

Configure Link Instances

Set and inspect link configuration with the MgslDlSetParams and MgslDlGetParams functions. These functions use the MGSL_DLPARAMS structure. The link configuration customizes the link layer behavior in order to implement specific layer 2 protocols such as LAPB or SNA SDLC.

Interacting with API Primitives

The following sections use the data link primitives with the MgslDlCall and MgslDlWait functions. An application uses MgslDlCall to make requests or respond to indications. The application calls MgslDlWait to wait for and process indications and confirmations. Multithreaded applications are well suited for these tasks. Typically, one thread continuously calls MgslDlWait, and dispatches indications and confirmations to primitive specific handlers. Other threads make requests to MgslDlCall as required by user actions or program requirements.

A thread that waits for indications and confirmations might look like this:

/* local variables */
PMGSL_PRIMITIVE Primitive;
OVERLAPPED ol;

/* create a manual reset event for use with API */
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if (!hEvent) {
    /* process error */
}
else
    ol.hEvent = hEvent;

/* allocate memory for the returned primitive */
Primitive = (PMGSL_PRIMITIVE)malloc(sizeof(MGSL_PRIMITIVE) + MAX_FRAME_SIZE);

while(ApplicationActive) {
    Primitive->Size = sizeof(MGSL_PRIMITIVE) + MAX_FRAME_SIZE;
    rc = MgslDlWait(hDevice, Primitive, &ol);
    if (rc != ERROR_SUCCESS && rc != ERROR_IO_PENDING) {
        /* process error */
        continue;
    }

    if (rc == ERROR_IO_PENDING)
        WaitForSingleObject(hEvent,INFINITE);

    /* process returned primitive based on Type and Link */
    switch(Primitive->Type) {
        case DLINDICATION_ESTABLISH:
            /* process */
            break;
        case DLCONFIRM_ESTABLISH:
            /* process */
            break;
            <…. Other possible indications and confirms ….>
    }
}

An example of a request to send data:

memcpy(Primitive->Buffer,DataBuffer,DataBufferSize);

Primitive.Link = Link;
Primitive.Type = DLREQUEST_DATA;
Primitive.Flags = 0;
Primitive.Size = DataBufferSize;

rc = MgslDlCall(hDevice, &Primitive);
if (rc != ERROR_SUCCESS) {
    /* process error */
}

Enable Link

Enable a link by setting DLFLAG_ENABLE in the parameters structure passed to MgslDlSetParams. This allows the link to receive frames. Optionally, set DLFLAG_ACCEPT to allow the peer to request establishment of operational mode, otherwise establishment requests by the peer are rejected with the appropriate link layer procedures. Once enabled, data may be exchanged using unacknowledged data transfer (DLREQUEST_UNITDATA).

Establish Link

Establish an operational mode with the DLREQUEST_ESTALISH primitive. If the link is enabled with the DLFLAG_ACCEPT flag set, the remote peer may request establishment, which results in a DLINDICATION_ESTABLISH locally.

Exchange Data

Once an operational mode is established, use DLREQUEST_DATA send data using acknowledged mode transfers. This offers increased reliability through link layer procedures for data sequencing and acknowledgement. Acknowledged data received from the peer is indicated with DLINDICATION_DATA.

Unacknowledged data may be transferred in an operational mode, using DLREQUEST_UNITDATA.

The application may encounter an ERROR_BUSY return code when sending data. This indicates that the API send buffers are full. The application should wait for DLINDICATION_SEND_READY before attempting to send more data.

When all send data has been sent, the API generates a DLINDICATION_DATA_DONE or DLINDICATION_UNITDATA_DONE. This can be used to determine when it is safe to disconnect.

The API generates a DLINDICATION_RCV_BUSY when the receiver busy state of the peer or local station changes. This is mainly for informational purposes. If the local receiver becomes busy, the application must read the queued receive data (MgslDlWait) to clear the receive buffers, and then call DLREQUEST_RCV_BUSY to clear the busy condition.

Release Link

When acknowledged mode transfer is no longer needed, release the link with DLREQUEST_RELEASE. When the request completes, a DLCONFIRM_RELEASE is generated, and the link is in disconnected mode. If the peer releases the link, a DLINDICATION_RELEASE is generated locally.

Free Link

When a link is no longer needed, the link must be freed to release resources used by the link. This is done by calling MgslDlFree. Once a link has been released, all configuration and state information is lost.

Close Physical Port

When the physical port is no longer required, close the port with MgslClose. This deactivates the physical port, and releases the port for further use by other processes.

Miscellaneous Functions

Station identification is exchanged using the DLREQUEST_XID, DLRESPONSE_XID, DLINDICATION_XID and DLCONFIRM_XID primitives. The XID feature is usually used for SNA SDLC applications. This feature is normally used in disconnected mode, but may be used in any mode.

A simple link test can be performed using the DLREQUEST_TEST and DLCONFIRM_TEST primitives. This sends a TEST frame and waits for a TEST response. The test feature can be used in any mode.

Sample Application

A sample application LLTEST.EXE is provided, with source code, to demonstrate the use of the API for LAPB and SNA SDLC communications. The application allows the user to transfer files and generate random traffic (both acknowledged and unacknowledged) while displaying link statistics. Configuration dialogs allow the user to customize the link operation. The XID and TEST options are also demonstrated.

Loop Mode Sample

Loop mode is a special mode of operation that connects multiple stations in a physical loop. Each transmit signal is connected to the receive signal of the next down loop neighbor. Loop mode operation uses normal response mode (NRM), with one station operating as the primary (loop controller or LC), and all other stations operating as secondary stations. Data is exchanged between the LC and secondary stations, but never directly between secondary stations. Data travels around the loop, with each secondary echoing data from the transmit to the receive signal, except when transmitting its own data.

For more details on loop mode communications, refer to IBM SDLC General Information (GA27-3093-2).

The sample application LLLOOP.EXE demonstrates the use of the link layer API in loop mode. One instance of the application operates as the loop controller. The LC allocates a single link to poll all stations on the loop. As each secondary station responds, the LC allocates a new link instance to service the station. Each secondary station will appear in the list of stations in the application window. All other instances of the application operate as secondary stations with a single link instance. Be careful to note how the port and link parameters are setup for both cases.


Previous Contents Next