Schreiben eines MBBCx-Clienttreibers
Warnung
Die Sequenzdiagramme in diesem Thema dienen nur zur Veranschaulichung. Sie sind keine öffentlichen Aufträge und unterliegen künftigen Änderungen.
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 universelle Anleitung , um sicherzustellen, dass die INF-Dateien die universellen Anforderungen erfüllen.
Initialisieren des Geräts
Zusätzlich zu den Aufgaben, die von NetAdapterCx für die NetAdapter-Geräteinitialisierung erforderlich sind, muss ein MBB-Clienttreiber auch die folgenden Aufgaben in seiner EvtDriverDeviceAdd-Rückruffunktion ausführen:
Rufen Sie MBB_DEVICE_CONFIG_INIT nach dem Aufruf von NetDeviceInitConfig , aber vor dem Aufruf von WdfDeviceCreate auf, wobei auf dasselbe WDFDEVICE_INIT objekt verwiesen wird, das vom Framework übergeben wurde.
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 veranschaulicht, wie das MBB-Gerät initialisiert wird. 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 Rückruffunktion EvtDriverDeviceAdd erstellen. Stattdessen wird es von MBBCx angewiesen, dies später zu tun.
Als Nächstes muss der Clienttreiber MbbDeviceSetMbimParameters aufrufen, in der Regel in der folgenden Rückruffunktion EvtDevicePrepareHardware .
Dieses Nachrichtenflussdiagramm veranschaulicht den Initialisierungsprozess.
Dieses Nachrichtenflussdiagramm veranschaulicht den Initialisierungsprozess.
Behandeln von MBIM-Steuerelementmeldungen
MBBCx verwendet die MBIM-Standardsteuerungsbefehle, die in der MBIM-Spezifikation Rev 1.0( Abschnitte 8, 9 und 10) für die Steuerungsebene definiert sind. Befehle und Antworten werden über eine Reihe von Rückruffunktionen ausgetauscht, die vom Clienttreiber und von MBBCx bereitgestellten APIs bereitgestellt werden. MBBCx imitiert das Betriebsmodell eines MBIM-Geräts, wie in MBIM-Spezifikation Rev 1.0, Abschnitt 5.3 definiert, mithilfe der folgenden Funktionsaufrufe:
- MBBCx sendet eine MBIM-Befehlsnachricht an den Clienttreiber, indem die Rückruffunktion EvtMbbDeviceSendMbimFragment aufgerufen wird. Der Clienttreiber schließt diese Sendeanforderung asynchron ab, indem MbbRequestComplete aufgerufen wird.
- Der Clienttreiber signalisiert die Verfügbarkeit des Ergebnisses, indem er MbbDeviceResponseAvailable aufruft.
- 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 kann MBBCx über ein nicht angefordertes Geräteereignis benachrichtigen, indem er MbbDeviceResponseAvailable aufruft. MBBCx ruft dann die Informationen vom Clienttreiber ab, ähnlich wie beim Abrufen von MBIM-Antwortnachrichten.
Das folgende Diagramm veranschaulicht den Nachrichtenaustauschfluss des MBBCx-Client-Treibers.
Synchronisierung von MBIM-Steuernachrichten
Das MBBCx-Framework serialisiert Aufrufe immer in den 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 , erhält 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 zunächst zu D0 (d. h. es ruft EvtDeviceD0Entry auf), bevor evtMbbDeviceSendMbimFragment oder EvtMbbDeviceReceiveMbimFragment aufgerufen wird. Das MBBCx-Framework garantiert auch, dass das Gerät im D0-Zustand beibehalten wird, d. h . evtDeviceD0Exit wird erst aufgerufen, wenn der Client MbbRequestComplete oder MbbRequestCompleteWithInformation aufruft.
Erstellen der NetAdapter-Schnittstelle für den PDP-Kontext/EPS-Bearer
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. Dies wird erreicht, indem MBBCx die Rückruffunktion EvtMbbDeviceCreateAdapter des Clienttreibers aufruft.
In der Implementierung der Rückruffunktion EvtMbbDeviceCreateAdapter muss der MBBCx-Clienttreiber zunächst die gleichen Aufgaben ausführen, die zum Erstellen eines NETADAPTER-Objekts erforderlich sind wie jeder NetAdapterCx-Clienttreiber. Darüber hinaus müssen die folgenden zusätzlichen Aufgaben ausgeführt werden:
Rufen Sie MbbAdapterInitialize für das von NetAdapterCreate erstellte NETADAPTER-Objekt auf.
Rufen Sie nach dem Aufruf von MbbAdapterinitializeMbbAdapterGetSessionId auf, um die Datensitzungs-ID erneut anzuzeigen, 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 bzw. standardmäßigen EPS-Bearer eingerichtet wurde.
Es wird empfohlen, dass MBBCx-Clienttreiber eine interne Zuordnung zwischen dem erstellten NETADAPTER-Objekt und der zurückgegebenen SessionId beibehalten. Dies hilft beim Nachverfolgen der Datensitzung-zu-NETADAPTER-Objektbeziehung, die besonders nützlich ist, wenn mehrere PDP-Kontexte/EPS-Bearer aktiviert wurden.
Vor der Rückkehr von EvtMbbDeviceCreateAdapter müssen Clienttreiber den Adapter starten, indem sie NetAdapterStart aufrufen. Optional können sie auch die Funktionen des Adapters festlegen, indem sie vor dem Aufruf von NetAdapterStart eine oder mehrere dieser Funktionen aufrufen:
MBBCx ruft diese Rückruffunktion mindestens einmal auf, sodass immer ein NETADPATER-Objekt für den primären PDP-Kontext bzw. den standardmäßigen EPS-Bearer vorhanden ist. Wenn mehrere PDP-Kontexte/EPS-Bearer aktiviert sind, ruft MBBCx diese Rückruffunktion möglicherweise mehrmals auf, einmal für jede zu erstellende Datensitzung. Es muss eine 1:1-Beziehung zwischen der durch das NETADAPTER-Objekt dargestellten Netzwerkschnittstelle und einer Datensitzung bestehen, wie im folgenden Diagramm dargestellt.
Das folgende Beispiel zeigt, wie Sie ein NETADAPTER-Objekt für eine Datensitzung erstellen. Beachten Sie, dass Fehlerbehandlung und Code, der zum Einrichten von Adapterfunktionen erforderlich ist, aus Gründen der Übersichtlichkeit und Übersichtlichkeit weggelassen werden.
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 Datapath-Funktionen 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.
Der Flow zum Erstellen des NETADAPTER-Objekts für den primären PDP-Kontext bzw. den standardmäßigen EPS-Bearer wird von MBBCx initiiert, wenn EvtDevicePrepareHardware erfolgreich abgeschlossen wurde.
Der Flow zum Erstellen des NETADAPTER-Objekts für den sekundären PDP-Kontext/dedizierten EPS-Bearer wird von WwanSvc ausgelöst, wenn Bedarfsverbindungen von Anwendungen angefordert werden.
Lebensdauer des NETADAPTER-Objekts
Das vom Clienttreiber erstellte NETADAPTER-Objekt wird von MBBCx automatisch 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 sauber muss, die an ein NETADAPTER-Objekt gebunden 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.
Behandeln von Gerätedienstsitzungen
Wenn eine Anwendung DSS-Daten an das Modemgerät sendet, ruft MBBCx die Rückruffunktion EvtMbbDeviceSendServiceSessionData des Clienttreibers auf. Der Clienttreiber sollte die Daten dann asynchron an das Gerät senden und MbbDeviceSendDeviceServiceSessionDataComplete aufrufen, sobald die Übermittlung abgeschlossen ist, damit MBBCx dann den für die Daten zugeordneten Arbeitsspeicher freigeben kann.
Umgekehrt ruft der Clienttreiber MbbDeviceReceiveDeviceServiceSessionData auf, um alle Daten über MBBCx an die Anwendung zu übergeben.
Anforderungen für Windows-Treiber
- Einhaltung der DCH-Entwurfsprinzipien
- Befolgen Sie die Prinzipien der Treiberpaketisolation .
- Api Layering-Anforderungen befolgen
- Zertifizieren mit dem Zertifizierungsprozess für das Windows-Hardwarekompatibilitätsprogramm mithilfe des Hardware Lab Kits