次の方法で共有


MBBCx クライアント ドライバーの作成

警告

このトピックのシーケンス図は、説明のみを目的としています。 これらはパブリック コントラクトではなく、将来変更される可能性があります。

MBBCx クライアント ドライバーの INF ファイル

MBBCx クライアント ドライバーの INF ファイルは、他の NetAdapterCx クライアント ドライバーと同じです。 詳細については、「NetAdapterCx クライアント ドライバーの INF ファイル」を参照してください。

ユニバーサル ガイダンスに従って、INF ファイルがユニバーサル要件を満たしていることを確認します。

デバイスを初期化する

NetAdapterCx が NetAdapter デバイスの初期化に必要とするタスクに加えて、MBB クライアント ドライバーは、EvtDriverDeviceAdd コールバック関数で次のタスクも実行する必要があります。

  1. NetDeviceInitConfig を呼び出した後、WdfDeviceCreate を呼び出す前に MBB_DEVICE_CONFIG_INIT を呼び出し、フレームワークによって渡されたのと同じWDFDEVICE_INIT オブジェクトを参照します。

  2. 初期化された MBB_DEVICE_CONFIG 構造体と WdfDeviceCreate から取得した WDFDEVICE オブジェクトを使用して、MbbDeviceInitialize を呼び出して MBB デバイス固有のコールバック関数を登録します。

次の例では、MBB デバイスを初期化する方法を示します。 わかりやすくするために、エラー処理コードは省略しています。

    status = NetDeviceInitConfig(deviceInit);
    status = MbbDeviceInitConfig(deviceInit);

    // Set up other callbacks such as Pnp and Power policy

    status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &wdfDevice);

    MBB_DEVICE_CONFIG mbbDeviceConfig;
    MBB_DEVICE_CONFIG_INIT(&mbbDeviceConfig,
                           EvtMbbDeviceSendMbimFragment,
                           EvtMbbDeviceReceiveMbimFragment,
                           EvtMbbDeviceSendServiceSessionData,
                           EvtMbbDeviceCreateAdapter);

    status = MbbDeviceInitialize(wdfDevice, &mbbDeviceConfig);

他の種類の NetAdapterCx ドライバーと異なり、MBB クライアント ドライバーは、EvtDriverDeviceAdd コールバック関数内から NETADAPTER オブジェクトを作成することができません。 代わりに、後で MBBCx によって指示されます。

次に、クライアント ドライバーは MbbDeviceSetMbimParameters を呼び出す必要があります。通常は、次の EvtDevicePrepareHardware コールバック関数で呼び出します。

このメッセージ フロー図は、初期化プロセスを示しています。

Diagram that shows the MBBCx client driver initialization process.

このメッセージ フロー図は、初期化プロセスを示しています。

Diagram that shows the MBBCx client driver initialization process.

MBIM 制御メッセージの処理

MBBCx は、MBIM 仕様 Rev 1.0、セクション 8、9、および 10 で定義されている標準の MBIM 制御コマンドをコントロール プレーンに使用します。 コマンドと応答は、クライアント ドライバーによって提供される一連のコールバック関数と、MBBCx によって提供される API を介して交換されます。 MBBCx は、次の関数呼び出しを使用して、MBIM 仕様 Rev 1.0、セクション 5.3 で定義されているように、MBIM デバイスの運用モデルを模倣します。

  • MBBCx は、EvtMbbDeviceSendMbimFragment コールバック関数を呼び出して、MBIM コマンド メッセージをクライアント ドライバーに送信します。 クライアント ドライバーは、MbbRequestComplete を呼び出すことで、この送信要求を非同期的に完了します。
  • クライアント ドライバーは、MbbDeviceResponseAvailable を呼び出すことで、結果の可用性を通知します。
  • MBBCx は、EvtMbbDeviceReceiveMbimFragment コールバック関数を呼び出すことで、クライアント ドライバーから MBIM 応答メッセージをフェッチします。 クライアント ドライバーは、MbbRequestCompleteWithInformation を呼び出 すことで、この get-response 要求を非同期的に完了します。
  • MBB クライアント ドライバーは、MbbDeviceResponseAvailable を呼び出すことで、未承諾のデバイス イベントを MBBCx に通知できます。 MBBCx は、MBIM 応答メッセージをフェッチする方法と同様に、クライアント ドライバーから情報を取得します。

次の図は、MBBCx-client ドライバーのメッセージ交換フローを示しています。

Diagram that shows the MBIM message exchange between MBBCx and the client driver.

MBIM 制御メッセージの同期

MBBCx フレームワークは、常にクライアント ドライバーの EvtMbbDeviceSendMbimFragment コールバック関数と EvtMbbDeviceReceiveMbimFragment コールバック関数への呼び出しをシリアル化します。 クライアント ドライバーが MbbRequestComplete または MbbRequestCompleteWithInformation を呼び出すまで、フレームワークによって新しい呼び出しは行われません。

クライアント ドライバーは、重複する EvtMbbDeviceSendMbimFragment コールバックまたは EvtMbbDeviceReceiveMbimFragment コールバックを受信しないことが保証されますが、デバイスから前のコマンドの応答を使用できるようになる前に、それらのコールバックに対する複数の呼び出しを連続して受け取ることがあります。

デバイスが D0 状態でない場合、MBBCx フレームワークは、EvtMbbDeviceSendMbimFragment または EvtMbbDeviceReceiveMbimFragment を呼び出す前に、バイスを D0 に取り込みます (つまり、EvtDeviceD0Entry を呼び出します)。 また、MBBCx フレームワークは、デバイスを D0 状態に保つことも保証します。つまり、クライアントが MbbRequestComplete または MbbRequestCompleteWithInformation を呼び出すまで、EvtDeviceD0Exit を呼び出しません。

PDP コンテキスト/EPS ベアラーの NetAdapter インターフェイスを作成する

データ セッションを確立する前に、MBBCx は、NETADAPTER オブジェクトを作成するようにクライアント ドライバーに指示し、アクティブ化されたデータ セッションのネットワーク インターフェイスを表すために MBBCx によって使用されます。 これは、クライアント ドライバーの EvtMbbDeviceCreateAdapter コールバック関数を呼び出す MBBCx によって実現されます。

EvtMbbDeviceCreateAdapter コールバック関数の実装では、MBBCx クライアント ドライバーは、まず、、NETADAPTER オブジェクトの作成に要する、NetAdapterCx クライアント ドライバーと同じタスクを実行する必要があります。 さらに、次の追加タスクも実行する必要があります。

  1. NetAdapterCreate によって作成された NETADAPTER オブジェクトで MbbAdapterInitialize を呼び出します。

  2. MbbAdapterinitialize を呼び出した後、MbbAdapterGetSessionId を呼び出して、MBBCx がこの NETADAPTER オブジェクトを使用するためのデータ セッション ID を取得します。 たとえば、戻り値が 0 の場合は、プライマリ PDP コンテキスト/既定の EPS ベアラーによって確立されたデータ セッションに対して、MBBCx がこの NETADAPTER インターフェイスを使用することを意味します。

  3. MBBCx クライアント ドライバーは、作成された NETADAPTER オブジェクトと返された SessionId の間に内部マッピングを保持することをお勧めします。 これは、データ セッションと NETADAPTER オブジェクトの関係を追跡するのに役立ち、複数の PDP コンテキスト/EPS ベアラーがアクティブになっている場合に特に便利です。

  4. EvtMbbDeviceCreateAdapter から戻る前に、クライアント ドライバーは NetAdapterStart を呼び出してアダプターを起動する必要があります。 必要に応じて、NetAdapterStart の呼び出しの前に次の関数を 1 つ以上呼び出して、アダプターの機能を設定することもできます。

MBBCx はこのコールバック関数を少なくとも 1 回呼び出します。そのため、プライマリ PDP コンテキスト/既定の EPS ベアラーには常に 1 つの NETADPATER オブジェクトがあります。 複数の PDP コンテキスト/EPS ベアラーがアクティブになっている場合、MBBCx は、確立されるすべてのデータ セッションに対して 1 回、このコールバック関数を複数回呼び出すことがあります。 次の図に示すように、NETADAPTER オブジェクトによって表されるネットワーク インターフェイスとデータ セッションの間に 1 対 1 のリレーションシップが必要です。

Diagram that shows multiple NETADAPTER objects for different data sessions.

次の例では、データ セッションの NETADAPTER オブジェクトの作成方法を示します。 簡潔でわかりやすくするために、アダプター機能の設定に必要なエラー処理とコードは省略されていることに注意してください。

    NTSTATUS
    EvtMbbDeviceCreateAdapter(
        WDFDEVICE  Device,
        PNETADAPTER_INIT AdapterInit
    )
    {
        // Get the client driver defined per-device context
        PMY_DEVICE_CONTEXT deviceContext = MyGetDeviceContext(Device);

        // Set up the client driver defined per-adapter context
        WDF_OBJECT_ATTRIBUTES adapterAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&adapterAttributes,
                                                MY_NETADAPTER_CONTEXT);


        // Create the NETADAPTER object
        NETADAPTER netAdapter;
        NTSTATUS status = NetAdapterCreate(AdapterInit,
                                           &adapterAttributes,
                                           &netAdapter);

        // Initialize the adapter for MBB
        status = MbbAdapterInitialize(netAdapter);

        // Retrieve the Session ID and use an array to store
        // the session <-> NETADAPTER object mapping
        ULONG sessionId;
        PMY_NETADAPTER_CONTEXT netAdapterContext = MyGetNetAdapterContext(netAdapter);

        netAdapterContext->NetAdapter = netAdapter;

        sessionId = MbbAdapterGetSessionId(netAdapter);

        netAdapterContext->SessionId = sessionId;

        deviceContext->Sessions[sessionId].NetAdapterContext = netAdapterContext;

        //
        // Optional: set adapter capabilities
        //
        ...
        NetAdapterSetDatapathCapabilities(netAdapter,
                                          &txCapabilities,
                                          &rxCapabilities);

        ...
        NetAdapterSetLinkLayerCapabilities(netAdapter,
                                           &linkLayerCapabilities);

        ...
        NetAdapterSetLinkLayerMtuSize(netAdapter,
                                      MY_MAX_PACKET_SIZE - ETHERNET_HEADER_LENGTH);

        //
        // Required: start the adapter
        //
        status = NetAdapterStart(netAdapter);

        return status;
    }

データパス機能を設定するコード例については、「ネットワーク データ バッファーの管理」を参照してください。

MBBCx では、同じセッション ID で MBIM_CID_CONNECTを要求する前に EvtMbbDeviceCreateAdapter を呼び出すことが保証されます。 次のフロー図は、NETADAPTER オブジェクトの作成におけるクライアント ドライバーとクラス拡張機能の間の相互作用を示しています。

Diagram that shows NETADAPTER creation and activation for an MBB client driver.

プライマリ PDP コンテキスト/既定の EPS ベアラーの NETADAPTER オブジェクトを作成するためのフローは、EvtDevicePrepareHardware が正常に完了したときに、MBBCx によって開始されます。

セカンダリ PDP コンテキスト/専用 EPS ベアラーの NETADAPTER オブジェクトを作成するためのフローは、アプリケーションによってオンデマンド接続が要求されるたびに WwanSvc によってトリガーされます。

NETADAPTER オブジェクトの有効期間

クライアント ドライバーによって作成された NETADAPTER オブジェクトは、使用されなくなったときに、MBBCx によって自動的に破棄されます。 たとえば、これは追加の PDP コンテキスト/EPS ベアラーが非アクティブ化された後に発生します。 MBBCx クライアント ドライバーは、作成する NETADAPTER オブジェクトで WdfObjectDelete を呼び出すことはできません。

クライアント ドライバーは、NETADAPTER オブジェクトに関連付けられているコンテキスト データをクリーンする必要がある場合、NetAdapterCreate を呼び出すときに、オブジェクト属性構造体に EvtDestroyCallback 関数を提供する必要があります。

MBB デバイスの電源管理

電源管理の場合、クライアント ドライバーは、他の種類の NetAdapterCx クライアント ドライバーと同様に NETPOWERSETTINGS オブジェクトを使用する必要があります。

デバイス サービス セッションの処理

アプリケーションが DSS データをモデム デバイスに送信するときに、MBBCx はクライアント ドライバーの EvtMbbDeviceSendServiceSessionData コールバック関数を呼び出します。 クライアント ドライバーは、デバイスに非同期的にデータを送信し、送信が完了したら MbbDeviceSendDeviceServiceSessionDataComplete を呼び出す必要があるため、MBBCx は、データに割り当てられたメモリを解放できます。

逆に、クライアント ドライバーは MbbDeviceReceiveDeviceServiceSessionData を呼び出して、MBBCx を介してアプリケーションにデータを渡します。

Windows ドライバの準拠要件