Freigeben über


Schreiben eines MBBCx-Clienttreibers

Warnung

Die Sequenzdiagramme in diesem Thema dienen nur zur Veranschaulichung. Sie sind keine öffentlichen Aufträge und können künftig geändert werden.

INF-Dateien für MBBCx-Clienttreiber

INF-Dateien für MBBCx-Clienttreiber sind identisch mit anderen NetAdapterCx-Clienttreibern. Weitere Informationen finden Sie unter INF-Dateien für NetAdapterCx-Clienttreiber.

Befolgen Sie die universellen Richtlinien , um sicherzustellen, dass die INF-Dateien die universellen Anforderungen erfüllen.

Initialisieren des Geräts

Zusätzlich zu diesen Aufgaben, die von NetAdapterCx für die Initialisierung des NetAdapter-Geräts benötigt werden, muss ein MBB-Clienttreiber auch die folgenden Aufgaben in seiner EvtDriverDeviceAdd-Rückruffunktion ausführen:

  1. Rufen Sie MBB_DEVICE_CONFIG_INIT nach dem Aufrufen von NetDeviceInitConfig auf, jedoch vor dem Aufrufen von WdfDeviceCreate, und beziehen Sie sich dabei auf dasselbe WDFDEVICE_INIT Objekt, das vom Framework übergeben wurde.

  2. Rufen Sie MbbDeviceInitialize auf, um MBB-gerätespezifische Rückruffunktionen mithilfe einer initialisierten MBB_DEVICE_CONFIG Struktur und des WDFDEVICE-Objekts zu registrieren, das von WdfDeviceCreate abgerufen wurde.

Im folgenden Beispiel wird das Initialisieren des MBB-Geräts veranschaulicht. Die Fehlerbehandlung wurde aus Gründen der Übersichtlichkeit ausgelassen.

    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);

Im Gegensatz zu anderen Typen von NetAdapterCx-Treibern dürfen MBB-Clienttreiber das NETADAPTER-Objekt nicht aus der EvtDriverDeviceAdd-Rückruffunktion erstellen. Stattdessen wird sie von MBBCx angewiesen, dies später zu tun.

Als Nächstes muss der Clienttreiber MbbDeviceSetMbimParameters aufrufen, in der Regel in der folgenden EvtDevicePrepareHardware-Rückruffunktion .

Dieses Nachrichtenflussdiagramm veranschaulicht den Initialisierungsprozess.

Diagramm, das den Initialisierungsprozess des MBBCx-Clienttreibers zeigt.

Dieses Nachrichtenflussdiagramm veranschaulicht den Initialisierungsprozess.

Diagramm, das den Initialisierungsprozess des MBBCx-Clienttreibers zeigt.

Behandlung von MBIM-Steuerungsnachrichten

MBBCx verwendet die standardmäßigen MBIM-Steuerelementbefehle, die in der MBIM-Spezifikation Rev 1.0, Abschnitt 8, 9 und 10 definiert sind, für die Steuerungsebene. Befehle und Antworten werden über eine Reihe von Rückruffunktionen ausgetauscht, die vom Clienttreiber und apIs bereitgestellt werden, die von MBBCx bereitgestellt werden. MBBCx imitiert das Betriebsmodell eines MBIM-Geräts, wie in der MBIM-Spezifikation Rev 1.0, Abschnitt 5.3 definiert, mithilfe dieser Funktionsaufrufe:

  • MBBCx sendet eine MBIM-Befehlsnachricht an den Clienttreiber, indem er seine EvtMbbDeviceSendMbimFragment-Rückruffunktion aufruft. Der Clienttreiber schließt diese Sendeanforderung asynchron durch Aufrufen von MbbRequestComplete ab.
  • Der Clienttreiber signalisiert die Verfügbarkeit des Ergebnisses durch Aufrufen von MbbDeviceResponseAvailable.
  • MBBCx ruft die MBIM-Antwortnachricht vom Clienttreiber ab, indem die Rückruffunktion EvtMbbDeviceReceiveMbimFragment aufgerufen wird. Der Clienttreiber schließt diese Get-Response-Anforderung asynchron ab, indem MbbRequestCompleteWithInformation aufgerufen wird.
  • Der MBB-Clienttreiber benachrichtigt MBBCx möglicherweise über ein nicht angefordertes Geräteereignis, indem MbbDeviceResponseAvailable aufgerufen wird. MBBCx ruft dann die Informationen vom Clienttreiber auf ähnliche Weise ab, wie MBIM-Antwortnachrichten abgerufen werden.

Das folgende Diagramm veranschaulicht den Nachrichtenaustauschfluss von MBBCx-Clienttreibern.

Diagramm, das den MBIM-Nachrichtenaustausch zwischen MBBCx und dem Clienttreiber zeigt.

Synchronisierung von MBIM-Steuerungsnachrichten

Das MBBCx-Framework serialisiert immer Aufrufe in die Rückruffunktionen EvtMbbDeviceSendMbimFragment und EvtMbbDeviceReceiveMbimFragment des Clienttreibers. Es werden keine neuen Aufrufe vom Framework ausgeführt, bis der Clienttreiber mbbRequestComplete oder MbbRequestCompleteWithInformation aufruft.

Während ein Clienttreiber garantiert keine überlappenden EvtMbbDeviceSendMbimFragment - oder EvtMbbDeviceReceiveMbimFragment-Rückrufe empfängt, empfängt er möglicherweise mehrere Aufrufe nacheinander, bevor die Antwort für einen vorherigen Befehl vom Gerät verfügbar ist.

Wenn sich das Gerät nicht im D0-Zustand befindet, bringt das MBBCx-Framework das Gerät zuerst auf D0 (d. h. es ruft EvtDeviceD0Entry) auf, bevor es EvtMbbDeviceSendMbimFragment oder EvtMbbDeviceReceiveMbimFragment aufruft. Das MBBCx-Framework garantiert auch, dass es das Gerät im D0-Zustand behält, was bedeutet, dass es EvtDeviceD0Exit nicht aufruft, bis der Client MbbRequestComplete oder MbbRequestCompleteWithInformation aufruft.

Erstellen der NetAdapter-Schnittstelle für den PDP-Kontext/EPS-Träger

Vor dem Einrichten einer Datensitzung weist MBBCx den Clienttreiber an, ein NETADAPTER-Objekt zu erstellen, und es wird von MBBCx verwendet, um die Netzwerkschnittstelle für die aktivierte Datensitzung darzustellen. Dazu ruft MBBCx die EvtMbbDeviceCreateAdapter-Rückruffunktion des Clienttreibers auf.

Bei der Implementierung der EvtMbbDeviceCreateAdapter-Rückruffunktion muss der MBBCx-Clienttreiber zuerst dieselben Aufgaben ausführen, die zum Erstellen eines NETADAPTER-Objekts wie jeder NetAdapterCx-Clienttreiber erforderlich sind. Darüber hinaus muss sie auch die folgenden zusätzlichen Aufgaben ausführen:

  1. Rufen Sie MbbAdapterInitialize für das netADAPTER-Objekt auf, das von NetAdapterCreate erstellt wurde.

  2. Rufen Sie nach dem Aufrufen von MbbAdapterinitializeMbbAdapterGetSessionId auf, um die Datensitzungs-ID abzurufen, für die MBBCx dieses NETADAPTER-Objekt verwenden möchte. Wenn der zurückgegebene Wert beispielsweise 0 ist, bedeutet dies, dass MBBCx diese NETADAPTER-Schnittstelle für die Datensitzung verwendet, die vom primären PDP-Kontext/standard-EPS-Bearer festgelegt wurde.

  3. Es wird empfohlen, dass MBBCx-Clienttreiber eine interne Zuordnung zwischen dem erstellten NETADAPTER-Objekt und der zurückgegebenen SessionId beibehalten. Dadurch können Sie die Datensitzungs-zu-NETADAPTER-Objektbeziehung nachverfolgen, was besonders nützlich ist, wenn mehrere PDP-Kontexte/EPS-Bearer aktiviert wurden.

  4. Vor der Rückgabe von EvtMbbDeviceCreateAdaptermüssen Clienttreiber den Adapter starten, indem NetAdapterStart-aufgerufen wird. Optional können sie auch die Funktionen des Adapters festlegen, indem sie eine oder mehrere dieser Funktionen aufrufen, bevor sie den Aufruf von NetAdapterStart-:

MBBCx ruft diese Rückruffunktion mindestens einmal auf, sodass es immer ein NETADPATER-Objekt für den primären PDP-Kontext/standard-EPS-Bearer gibt. Wenn mehrere PDP-Kontexte/EPS-Bearer aktiviert werden, kann MBBCx diese Rückruffunktion mehrmals aufrufen, einmal für jede Datensitzung, die eingerichtet werden soll. Es muss eine 1:1-Beziehung zwischen der Netzwerkschnittstelle vorhanden sein, die durch das NETADAPTER-Objekt und eine Datensitzung dargestellt wird, wie im folgenden Diagramm dargestellt.

Diagramm, das mehrere NETADAPTER-Objekte für verschiedene Datensitzungen zeigt.

Das folgende Beispiel zeigt, wie Sie ein NETADAPTER-Objekt für eine Datensitzung erstellen. Beachten Sie, dass fehlerbehandlung und Code, der für das Einrichten von Adapterfunktionen erforderlich ist, aus Platzgründen und Übersichtlichkeit ausgelassen wird.

    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;
    }

Ein Codebeispiel zum Festlegen von Datenpfadfunktionen finden Sie unter Netzwerkdatenpufferverwaltung.

MBBCx garantiert, dass EvtMbbDeviceCreateAdapter aufgerufen wird, bevor MBIM_CID_CONNECT mit derselben Sitzungs-ID angefordert wird. Das folgende Flussdiagramm zeigt die Interaktionen zwischen dem Clienttreiber und der Klassenerweiterung beim Erstellen des NETADAPTER-Objekts.

Diagramm, das das Erstellen und Aktivieren von NETADAPTER für einen MBB-Clienttreiber zeigt.

Der Flow zum Erstellen des NETADAPTER-Objekts für den primären PDP-Kontext/Standard-EPS-Träger wird von MBBCx initiiert, wenn EvtDevicePrepareHardware erfolgreich abgeschlossen wurde.

Der Ablauf zum Erstellen des NETADAPTER-Objekts für den sekundären PDP-Kontext/dedizierte EPS-Bearer wird von WwanSvc ausgelöst, wenn On-Demand-Verbindungen von Anwendungen angefordert werden.

Lebensdauer des NETADAPTER-Objekts

Das vom Clienttreiber erstellte NETADAPTER-Objekt wird automatisch von MBBCx zerstört, wenn es nicht mehr verwendet wird. Dies geschieht beispielsweise, nachdem zusätzliche PDP-Kontext-/EPS-Bearer deaktiviert wurden. MBBCx-Clienttreiber dürfen WdfObjectDelete nicht für die von ihnen erstellten NETADAPTER-Objekte aufrufen.

Wenn ein Clienttreiber Kontextdaten bereinigen muss, die mit einem NETADAPTER-Objekt verknüpft sind, sollte er beim Aufrufen von NetAdapterCreate eine EvtDestroyCallback-Funktion in der Objektattributestruktur bereitstellen.

Energieverwaltung des MBB-Geräts

Für die Energieverwaltung sollten Clienttreiber das NETPOWERSETTINGS-Objekt wie andere Typen von NetAdapterCx-Clienttreibern verwenden.

Umgang mit Gerätedienst-Sitzungen

Wenn eine Anwendung DSS-Daten an das Modemgerät sendet, ruft MBBCx die EvtMbbDeviceSendServiceSessionData-Rückruffunktion des Clienttreibers auf. Der Clienttreiber sollte dann die Daten asynchron an das Gerät senden und MbbDeviceSendDeviceServiceSessionDataComplete aufrufen, sobald die Übermittlung abgeschlossen ist, sodass MBBCx dann den für die Daten zugeordneten Speicher freigeben kann.

Umgekehrt ruft der Clienttreiber MbbDeviceReceiveDeviceServiceSessionData auf, um alle Daten über MBBCx an die Anwendung zu übergeben.

Windows-Treiberkonforme Anforderungen