6.12 Line-Up Indication

From the telephony standpoint, the life of a call is a series of state transitions. For outgoing calls, a typical sequence of states might be: dialing, proceeding, ringing, connected, disconnected, and finally, idle. For an incoming call, this sequence might look as follows: offering, ringing, connected, disconnected, and finally, idle. In either case, the transition to the connected state is of particular interest, since this is the state in which data can flow across the wire.

A WAN miniport calls NdisMIndicateStatus with a GeneralStatus value of NDIS_STATUS_WAN_LINE_UP to indicate that a new data channel has become active. The buffer at StatusBuffer is formatted as an NDIS_MAC_LINE_UP structure. Prior to indicating a line up, the adapter will accept frames and can let them succeed or fail, but it is unlikely that such packets will actually be received by any remote system. Before a line-up indication, protocols are encouraged to reduce their timers and retry counts so that any outgoing connection attempts quickly fail.

An NDIS_STATUS_WAN_LINE_UP status must be completed prior to returning from the OID_TAPI_GET_ID request. The NdisLinkContext returned from the NDIS_STATUS_WAN_LINE_UP indication is passed back in the NDIS_TAPI_GET_ID structure as the DeviceID.

The NDIS_STATUS_WAN_LINE_UP must also be completed prior to indicating the LINECALLSTATE_CONNECTED to NDISWAN. Otherwise, the user-mode client of the connection might attempt to send data on a connection before NDISWAN is aware of the line.

When the line-up indication completes, NDISWAN and the miniport have exchanged handles, one that NDISWAN uses to subsequently direct send packets onto a data channel and the other that the miniport uses to identify the correct data channel for sends and in any status indications it makes to NDISWAN. Before NDISWAN gets a line-up indication and establishes a data channel for a particular call instance, it will not pass send packets on to the miniport's MiniportWanSend function.

A miniport indicates a line-up status in the context of an OID_TAPI_GET_ID request if either of the following occurs:

·The ulSelect member of NDIS_TAPI_GET_ID structure is set to LINECALLSELECT_CALL, and

·This request is the first OID_TAPI_GET_ID request for the hdCall member of the NDIS_TAPI_GET_ID structure

or

·The ulSelect member of NDIS_TAPI_GET_ID structure is set to LINECALLSELECT_CALL, and

·This request is not the first OID_TAPI_GET_ID request for the hdCall member of the NDIS_TAPI_GET_ID structure, but the DeviceClass is different from any previous get-id request for this call instance, and

·The miniport supports separate data channels for different device classes.

The StatusBuffer passed to NdisMIndicateStatus should point to a buffer of type NDIS_MAC_LINE_UP. This structure has the following definition:

typedef struct _NDIS_MAC_LINE_UP {
IN ULONG LinkSpeed;
IN NDIS_WAN_QUALITY Quality;
IN USHORT SendWindow;
IN NDIS_HANDLE ConnectionWrapperID;
IN NDIS_HANDLE NdisLinkHandle;
IN OUT NDIS_HANDLE NdisLinkContext;
} NDIS_MAC_LINE_UP, *PNDIS_MAC_LINE_UP;

The WAN miniport NIC driver should set the value of the ConnectionWrapperID member in the NDIS_MAC_LINE_UP structure to that of the htCall (the TAPI call handle) associated with the call because it is guaranteed to be unique across all telephony-capable miniports. The ConnectionWrapperID is valid until the miniport issues a line-down indication.

The NdisLinkHandle represents the miniport's handle for this data channel on this call instance. Typically it references the state the miniport maintains for this call. NDISWAN will retain this handle and return it to the miniport on any sends on this data channel. The NdisLinkContext is set to NULL when the miniport calls NdisMIndicateStatus. It will be set to a value supplied by NDISWAN before returning from NdisMIndicateStatus. This opaque handle must be retained by the miniport and supplied in subsequent calls to NDISWAN regarding this link, for instance to NdisMWanIndicateReceive.

The NdisLinkContext must be returned in the DeviceID member of NDIS_TAPI_GET_ID when MiniportQueryInformation returns from the OID_TAPI_GET_ID request. This context binds the call connection and the device class as seen by NDISTAPI with a handle that NDISWAN recognizes and has tied to a particular data channel. NDISWAN uses this handle to ensure that packets from a TAPI client are directed by NDISWAN to the correct miniport data channel.

Changing the Send Window

The SendWindow member of the NDIS_MAC_LINE_UP structure specified in a line-up indication acts as a throttle, controlling how many packets NDISWAN passes to a MiniportWanSend function for a particular line before it starts queuing packets. The MaxTransmit member of NDIS_WAN_INFO returned in response to the OID_WAN_GET_INFO request during driver initialization represents a default value for this window for all lines supported by an adapter. The miniport can reset the send window value on a per-line basis when it makes the first line-up indication for a new line. It can also change this send window value for a line dynamically by making a subsequent line-up indication to NDISWAN with a new nonzero SendWindow. That is, the miniport does not have to wait for an incoming or outgoing call to generate a line-up indication. If a miniport specifies a SendWindow of zero, NDISWAN will revert to using the default MaxTransmit value as the send window.

If the miniport makes a line-up indication to change the SendWindow, it must fill in both the NdisLinkHandle and NdisLinkContext members with the values that apply to the data channel on which the send window is to be changed. LinkSpeed and Quality are set to zero or possibly to new values. Both LinkSpeed and Quality can also be changed dynamically and independently by making a line-up indication and resetting the value(s).